Asp.net-Core

如何在 ABP Core Zero 中使用多個數據庫?

  • January 27, 2021

我想將“帳戶”表與“數據”表隔離開,以便在另一個應用程序上重用。

我嘗試使用 .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”項目中為您的表創建模式類。

[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”項目)中創建/使用“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”文件。

FirstDatabase 設置 -

連接到第一個數據庫所需的文件 -

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.**在“MultipleDbContextEfCoreDemo.Application”項目中使用 Dto、介面和服務類創建服務。

ITestAppService.cs-

public interface ITestAppService : IApplicationService
   {
       List<string> GetStudentAndCourses();

    }

測試應用服務.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 項目中使用服務。

引用自:https://stackoverflow.com/questions/49243891