ABP EF Core多数据库支持

12 篇文章 2 订阅

ABP官方Demo中提供了在EF Core中如何实现多数据库支持的例子,但Demo说明文档中对于要做哪些修改没做说明,所以本文在此做下说明。

首先要说明的是(我这边通过官方模板生成时输入的项目名称为TaobaoAuthorization),除了ConnectionStringName声明是在TaobaoAuthorizationConsts中外,所有修改均在TaobaoAuthorization.EntityFrameworkCore项目中。

为了支持多数据库,你需要做以下调整

  • DbContextOptionsConfigurerConfigure方法修改为泛型方法,这样你就不需要像官方Demo那样实现两个DbContextOptionsConfigurer
    public static class DbContextOptionsConfigurer
    {
        public static void Configure<T>(
            DbContextOptionsBuilder<T> dbContextOptions,
            string connectionString
            )
            where T : AbpDbContext
        {
            /* This is the single point to configure DbContextOptions for TaobaoAuthorizationDbContext */
            //dbContextOptions.UseSqlServer(connectionString);
            dbContextOptions.UseMySql(connectionString);
        }

        public static void Configure<T>(
            DbContextOptionsBuilder<T> dbContextOptions,
            DbConnection connection
            )
            where T : AbpDbContext
        {
            /* This is the single point to configure DbContextOptions for TaobaoAuthorizationDbContext */
            //dbContextOptions.UseSqlServer(connectionString);
            dbContextOptions.UseMySql(connection);
        }
    }
  • 增加其它数据库对应的DbContext,这里除了默认的TaobaoAuthorizationDbContext外,我们再新增了TaobaoAuthorizedDbContext
  • 调整并新增其他数据库对应的DbContextFactory,这里还是提取了一个抽象类出来
    /// <summary>
    /// EF Core PMC commands 基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class DbContextFactory<T> : IDesignTimeDbContextFactory<T>
        where T : AbpDbContext
    {
        /// <summary>
        /// 要采用的数据库连接节点名称
        /// </summary>
        public abstract string ConnectionStringName { get; }
        /// <summary>
        /// 创建DbContext实例
        /// 如果觉得每个数据库都要自己new太low,那么可以采用反射来动态创建,毕竟这里也只是PMC command使用的
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public abstract T CreateDbContext(DbContextOptions<T> options);
        public T CreateDbContext(string[] args)
        {
            var builder = new DbContextOptionsBuilder<T>();
            var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
            DbContextOptionsConfigurer.Configure(
                builder,
                configuration.GetConnectionString(ConnectionStringName)
            );
            return this.CreateDbContext(builder.Options);
        }
    }

然后将原先官网生成的相应DbContextFactory进行调整,如果还有其它数据库也只要继承DbContextFactory<T>即可

    /* This class is needed to run EF Core PMC commands. Not used anywhere else */
    public class TaobaoAuthorizationDbContextFactory : DbContextFactory<TaobaoAuthorizationDbContext>
    {//第一个数据库配置
        public override string ConnectionStringName => TaobaoAuthorizationConsts.DefaultConnectionStringName;

        public override TaobaoAuthorizationDbContext CreateDbContext(DbContextOptions<TaobaoAuthorizationDbContext> options)
        {
            return new TaobaoAuthorizationDbContext(options);
        }
    }

    public class TaobaoAuthorizedDbContextFactory : DbContextFactory<TaobaoAuthorizedDbContext>
    {//第二个数据库配置
        public override string ConnectionStringName => TaobaoAuthorizationConsts.AuthorizedConnectionStringName;

        public override TaobaoAuthorizedDbContext CreateDbContext(DbContextOptions<TaobaoAuthorizedDbContext> options)
        {
            return new TaobaoAuthorizedDbContext(options);
        }
    }
  • 增加MyConnectionStringResolver,ABP如何分辨应该用哪个数据库连接就是在这里定义的,当然这里还是在官网Demo的基础上略作调整,实际可以考虑增加Dictionary<Type,string>来实现DbContext与配置中ConnectionStringName的映射关系
    public class MyConnectionStringResolver : DefaultConnectionStringResolver
    {
        public MyConnectionStringResolver(IAbpStartupConfiguration configuration)
            : base(configuration)
        {
        }

        public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
        {
            var connectStringName = this.GetConnectionStringName(args);
            if (connectStringName != null)
            {
                var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
                return configuration.GetConnectionString(connectStringName);
            }
            return base.GetNameOrConnectionString(args);
        }
        private string GetConnectionStringName(ConnectionStringResolveArgs args)
        {
            var type = args["DbContextConcreteType"] as Type;
            if (type == typeof(TaobaoAuthorizedDbContext))
            {
                return TaobaoAuthorizationConsts.AuthorizedConnectionStringName;//返回数据库二的节点名称
            }
            return null;//采用默认数据库
        }
    }
  • 调整模板生成的EntityFrameworkCoreModule,增加PreInitialize实现,注意需要添加引用using Abp.Configuration.Startup,如果你还有其它数据库连接,那么也只要再依样新增AddDbContext即可
        public override void PreInitialize()
        {
            base.PreInitialize();
            Configuration.ReplaceService<IConnectionStringResolver, MyConnectionStringResolver>();
            this.AddDbContext<TaobaoAuthorizationDbContext>();//数据库一
            this.AddDbContext<TaobaoAuthorizedDbContext>();//数据库二
        }
        private void AddDbContext<TDbContext>()
            where TDbContext: AbpDbContext
        {
            Configuration.Modules.AbpEfCore().AddDbContext<TDbContext>(options =>
            {
                if (options.ExistingConnection != null)
                {
                    DbContextOptionsConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
                }
                else
                {
                    DbContextOptionsConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
                }
            });
        }

至此你就已经完成了ABP多数据库支持的代码调整工作,上述代码均可在这里找到。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值