【问题标题】:How to use multiples databases in ABP Core Zero?如何在 ABP Core Zero 中使用多个数据库?
【发布时间】:2018-03-12 20:27:21
【问题描述】:

我想将“帐户”表与“数据”表隔离开,以便在另一个应用程序上重复使用。
我尝试使用 .NET Core 2.0 + Angular 模板,创建 2 个连接字符串,但是当创建另一个 AbpDbContext 时,我无法为上下文设置连接字符串。
在其 GitHub 上使用多个 DB 上下文的示例使用 .NET 框架,而不是 .NET 核心,允许在 dbcontext ctor 上设置连接字符串。 如何在 .net core 2 模板上执行此操作?

【问题讨论】:

    标签: asp.net-core .net-core aspnetboilerplate


    【解决方案1】:

    在 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”文件。

    第一个数据库设置 -

    连接到第一个数据库所需的文件 -

    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”文件,将“IConnectionStringResolver”替换为我们的自定义实现 MyConnectionStringResolver。

    [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();
    
         }
    

    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 项目中使用服务。

    【讨论】:

    • 是的!我喜欢你的回答。我会测试它。谢谢!
    • 我使用了这段代码,虽然它适用于我的本地 appsettings 文件,但我在处理用户机密或 Azure AppService 设置时遇到了困难。我认为它可能在 AppConfigurations.Get(...) 中缺少环境和 userSecrets: true。您可以注入 IHostingEnvironment 以在运行时访问该信息。类似于: var configuration = AppConfigurations.Get(_env.ContentRootPath, _env.EnvironmentName, _env.IsDevelopment());
    • 如果您对第 5 步有疑问,请确保您引用的是 Abp.Configuration.Startup
    【解决方案2】:

    在导航属性方面,我遇到了与 @Sniipe 相同的问题。

    问题是我继承自

     AbpZeroDbContext<Tenant, Role, User, PortalDbContext>
    

    在我的第二个 DBContext 中,而不仅仅是

    AbpDbContext
    

    【讨论】:

    • 埃蒙,谢谢。我相信第二个 dbcontext 试图链接到我的主数据库中的用户。
    猜你喜欢
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 2018-01-25
    • 2015-10-29
    • 2021-05-11
    相关资源
    最近更新 更多