如何在 ASP Core Zero 中使用多个数据库?
How to use multiples databases in ABP Core Zero?
我想从 "data" 表中分离出 "account" 表,以便在另一个应用程序上重复使用。
我尝试使用 .NET Core 2.0 + Angular 模板,创建 2 个连接字符串,但是当创建另一个 AbpDbContext 时,我无法为上下文设置连接字符串。
在 GitHub 上使用多个 DB 上下文的示例使用 .NET 框架,而不是 .NET 核心,允许在 dbcontext ctor 上设置连接字符串。
我如何在 .net core 2 模板上执行此操作?
在 ASP.NET ZERO/ASP.NET BOILERPLATE.
中连接多个数据库
注意 - 使用单独的数据库上下文来使用多个数据库。
第 1 步。 在 "MultipleDbContextEfCoreDemo.Core" 项目中为您的表创建模式 class。
[Table ("tblStudent")] //Is in First Database
public class Student : Entity<long> {
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
protected Student () { }
}
[Table ("tblCourses")] //Is in Second Database
public class Courses : Entity<long> {
public int ID { get; set; }
public string CourseName { get; set; }
public string Standard { get; set; }
protected Courses () { }
}
第 2 步。 在同一项目中("MultipleDbContextEfCoreDemo.Core" 项目)create/use "MultipleDbContextEfCoreDemoConsts.cs" 添加数据库连接名称的文件。
public class MultipleDbContextEfCoreDemoConsts
{
public const string LocalizationSourceName = "MultipleDbContextEfCoreDemo";
public const string ConnectionStringName = "Default";
public const string SecondDbConnectionStringName = "Second";
}
步骤 3. 在 "MultipleDbContextEfCoreDemo.EntityFrameworkCore" 项目中转到 "EntityFrameworkCore" 文件夹并为每个数据库创建单独的 "DBContext" 和 "DbContextConfigurer" 文件您要连接的连接。
第一个数据库设置-
连接到第一个数据库所需的文件 -
1. FirstDbContext.cs
public class FirstDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
/* Define an IDbSet for each entity of the application */
public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
public virtual DbSet<Student> Student { get; set; }
public FirstDbContext (DbContextOptions<FirstDbContext> options) : base (options) {
}
protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}
2。 FirstDbContextConfigurer
public static class FirstDbContextConfigurer {
public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, string connectionString) {
builder.UseSqlServer (connectionString);
}
public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, DbConnection connection) {
builder.UseSqlServer (connection);
}
}
第二个数据库设置 -
连接到第二个数据库所需的文件 -
1. SecondDbContext.cs
public class SecondDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
/* Define an IDbSet for each entity of the application */
public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
public virtual DbSet<Student> Student { get; set; }
public SecondDbContext (DbContextOptions<SecondDbContext> options) : base (options) {
}
protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}
2。 SecondDbContextConfigurer
public static class SecondDbContextConfigurer {
public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, string connectionString) {
builder.UseSqlServer (connectionString);
}
public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, DbConnection connection) {
builder.UseSqlServer (connection);
}
}
步骤 4. 然后在同一个项目("MultipleDbContextEfCoreDemo.EntityFrameworkCore")中添加 "MyConnectionStringResolver.cs"
public class MyConnectionStringResolver : DefaultConnectionStringResolver
{
public MyConnectionStringResolver(IAbpStartupConfiguration configuration)
: base(configuration)
{
}
public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
{
if (args["DbContextConcreteType"] as Type == typeof(SecondDbContext))
{
var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
return configuration.GetConnectionString(MultipleDbContextEfCoreDemoConsts.SecondDbConnectionStringName);
}
return base.GetNameOrConnectionString(args);
}
}
步骤 5. 然后在同一个项目("MultipleDbContextEfCoreDemo.EntityFrameworkCore")中,更新 "MultipleDbContextEfCoreDemoEntityFrameworkCoreModule.cs" 文件以用我们的自定义实现 MyConnectionStringResolver 替换 "IConnectionStringResolver" .
[DependsOn(typeof(MultipleDbContextEfCoreDemoCoreModule), typeof(AbpEntityFrameworkCoreModule))]
public class MultipleDbContextEfCoreDemoEntityFrameworkCoreModule : AbpModule
{
public override void PreInitialize()
{
Configuration.ReplaceService<IConnectionStringResolver, MyConnectionStringResolver>();
// Configure first DbContext
Configuration.Modules.AbpEfCore().AddDbContext<FirstDbContext>(options =>
{
if (options.ExistingConnection != null)
{
FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
}
else
{
FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
}
});
// Configure second DbContext
Configuration.Modules.AbpEfCore().AddDbContext<SecondDbContext>(options =>
{
if (options.ExistingConnection != null)
{
SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
}
else
{
SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
}
});
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(MultipleDbContextEfCoreDemoEntityFrameworkCoreModule).GetAssembly());
}
}
步骤 6. 使用 Dto、接口和服务 Class 在 "MultipleDbContextEfCoreDemo.Application" 项目中创建服务 Class。
ITestAppService.cs-
public interface ITestAppService : IApplicationService
{
List<string> GetStudentAndCourses();
}
TestAppService.cs
public class TestAppService : MultipleDbContextEfCoreDemoAppServiceBase, ITestAppService
{
private readonly IRepository<Student> _studentRepository; //in the first db
private readonly IRepository<Courses> _coursesRepository; //in the second db
public TestAppService(
IRepository<Student> studentRepository,
IRepository<Courses> coursesRepository
)
{
_studentRepository = studentRepository;
_coursesRepository = coursesRepository;
}
//a sample method uses both databases concurrently
public List<string> GetStudentAndCourses()
{
List<string> names = new List<string>();
var studentNames = _studentRepository.GetAllList().Select(p => "Student: " + p.FirstName).ToList();
names.AddRange(peopleNames);
var courseNames = _coursesRepository.GetAllList().Select(p => "Course: " + p.CourseName).ToList();
names.AddRange(courseNames);
return names;
}
}
步骤 7. 将数据库连接字符串添加到您的 MultipleDbContextEfCoreDemo.Web/MultipleDbContextEfCoreDemo.Web.Host 项目的
"appsettings.json" 文件。
{
"ConnectionStrings": {
"Default":
"Server=XXX.XXX.XX.XX;Database=firstDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;",
"Second":
"Server=XXX.XXX.XX.XX;Database=secondDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;"
}
}
第 8 步。 在您的 angular/MVC 项目中使用服务。
我 运行 在导航属性方面遇到了与@Sniipe 相同的问题。
问题是我继承自
AbpZeroDbContext<Tenant, Role, User, PortalDbContext>
在我的第二个 DBContext 而不是
AbpDbContext
我想从 "data" 表中分离出 "account" 表,以便在另一个应用程序上重复使用。
我尝试使用 .NET Core 2.0 + Angular 模板,创建 2 个连接字符串,但是当创建另一个 AbpDbContext 时,我无法为上下文设置连接字符串。
在 GitHub 上使用多个 DB 上下文的示例使用 .NET 框架,而不是 .NET 核心,允许在 dbcontext ctor 上设置连接字符串。
我如何在 .net core 2 模板上执行此操作?
在 ASP.NET ZERO/ASP.NET BOILERPLATE.
中连接多个数据库注意 - 使用单独的数据库上下文来使用多个数据库。
第 1 步。 在 "MultipleDbContextEfCoreDemo.Core" 项目中为您的表创建模式 class。
[Table ("tblStudent")] //Is in First Database
public class Student : Entity<long> {
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
protected Student () { }
}
[Table ("tblCourses")] //Is in Second Database
public class Courses : Entity<long> {
public int ID { get; set; }
public string CourseName { get; set; }
public string Standard { get; set; }
protected Courses () { }
}
第 2 步。 在同一项目中("MultipleDbContextEfCoreDemo.Core" 项目)create/use "MultipleDbContextEfCoreDemoConsts.cs" 添加数据库连接名称的文件。
public class MultipleDbContextEfCoreDemoConsts
{
public const string LocalizationSourceName = "MultipleDbContextEfCoreDemo";
public const string ConnectionStringName = "Default";
public const string SecondDbConnectionStringName = "Second";
}
步骤 3. 在 "MultipleDbContextEfCoreDemo.EntityFrameworkCore" 项目中转到 "EntityFrameworkCore" 文件夹并为每个数据库创建单独的 "DBContext" 和 "DbContextConfigurer" 文件您要连接的连接。
第一个数据库设置-
连接到第一个数据库所需的文件 -
1. FirstDbContext.cs
public class FirstDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
/* Define an IDbSet for each entity of the application */
public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
public virtual DbSet<Student> Student { get; set; }
public FirstDbContext (DbContextOptions<FirstDbContext> options) : base (options) {
}
protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}
2。 FirstDbContextConfigurer
public static class FirstDbContextConfigurer {
public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, string connectionString) {
builder.UseSqlServer (connectionString);
}
public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, DbConnection connection) {
builder.UseSqlServer (connection);
}
}
第二个数据库设置 -
连接到第二个数据库所需的文件 -
1. SecondDbContext.cs
public class SecondDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
/* Define an IDbSet for each entity of the application */
public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
public virtual DbSet<Student> Student { get; set; }
public SecondDbContext (DbContextOptions<SecondDbContext> options) : base (options) {
}
protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}
2。 SecondDbContextConfigurer
public static class SecondDbContextConfigurer {
public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, string connectionString) {
builder.UseSqlServer (connectionString);
}
public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, DbConnection connection) {
builder.UseSqlServer (connection);
}
}
步骤 4. 然后在同一个项目("MultipleDbContextEfCoreDemo.EntityFrameworkCore")中添加 "MyConnectionStringResolver.cs"
public class MyConnectionStringResolver : DefaultConnectionStringResolver
{
public MyConnectionStringResolver(IAbpStartupConfiguration configuration)
: base(configuration)
{
}
public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
{
if (args["DbContextConcreteType"] as Type == typeof(SecondDbContext))
{
var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
return configuration.GetConnectionString(MultipleDbContextEfCoreDemoConsts.SecondDbConnectionStringName);
}
return base.GetNameOrConnectionString(args);
}
}
步骤 5. 然后在同一个项目("MultipleDbContextEfCoreDemo.EntityFrameworkCore")中,更新 "MultipleDbContextEfCoreDemoEntityFrameworkCoreModule.cs" 文件以用我们的自定义实现 MyConnectionStringResolver 替换 "IConnectionStringResolver" .
[DependsOn(typeof(MultipleDbContextEfCoreDemoCoreModule), typeof(AbpEntityFrameworkCoreModule))]
public class MultipleDbContextEfCoreDemoEntityFrameworkCoreModule : AbpModule
{
public override void PreInitialize()
{
Configuration.ReplaceService<IConnectionStringResolver, MyConnectionStringResolver>();
// Configure first DbContext
Configuration.Modules.AbpEfCore().AddDbContext<FirstDbContext>(options =>
{
if (options.ExistingConnection != null)
{
FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
}
else
{
FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
}
});
// Configure second DbContext
Configuration.Modules.AbpEfCore().AddDbContext<SecondDbContext>(options =>
{
if (options.ExistingConnection != null)
{
SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
}
else
{
SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
}
});
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(MultipleDbContextEfCoreDemoEntityFrameworkCoreModule).GetAssembly());
}
}
步骤 6. 使用 Dto、接口和服务 Class 在 "MultipleDbContextEfCoreDemo.Application" 项目中创建服务 Class。
ITestAppService.cs-
public interface ITestAppService : IApplicationService
{
List<string> GetStudentAndCourses();
}
TestAppService.cs
public class TestAppService : MultipleDbContextEfCoreDemoAppServiceBase, ITestAppService
{
private readonly IRepository<Student> _studentRepository; //in the first db
private readonly IRepository<Courses> _coursesRepository; //in the second db
public TestAppService(
IRepository<Student> studentRepository,
IRepository<Courses> coursesRepository
)
{
_studentRepository = studentRepository;
_coursesRepository = coursesRepository;
}
//a sample method uses both databases concurrently
public List<string> GetStudentAndCourses()
{
List<string> names = new List<string>();
var studentNames = _studentRepository.GetAllList().Select(p => "Student: " + p.FirstName).ToList();
names.AddRange(peopleNames);
var courseNames = _coursesRepository.GetAllList().Select(p => "Course: " + p.CourseName).ToList();
names.AddRange(courseNames);
return names;
}
}
步骤 7. 将数据库连接字符串添加到您的 MultipleDbContextEfCoreDemo.Web/MultipleDbContextEfCoreDemo.Web.Host 项目的 "appsettings.json" 文件。
{
"ConnectionStrings": {
"Default":
"Server=XXX.XXX.XX.XX;Database=firstDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;",
"Second":
"Server=XXX.XXX.XX.XX;Database=secondDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;"
}
}
第 8 步。 在您的 angular/MVC 项目中使用服务。
我 运行 在导航属性方面遇到了与@Sniipe 相同的问题。
问题是我继承自
AbpZeroDbContext<Tenant, Role, User, PortalDbContext>
在我的第二个 DBContext 而不是
AbpDbContext