zoukankan      html  css  js  c++  java
  • 在.net core中完美解决多租户分库分表的问题

     前几天有人想做一个多租户的平台,每个租户一个库,可以进行水平扩展,应用端根据登录信息,切换到不同的租户库

    计划用ef core实现,他们说做不出来,需要动态创建dbContext,不好实现

    然而这个使用CRL很轻松就能解决了

    以下为演示数据库,有两个库testdb和testdb2,查询结果如下

    目标:

    根据传入登录信息连不不同的库,查询返回结果,如登录人为01,返回d1.default,登录人为02 返回 d2.default

    实际上这个需求就是分库分表的实现,通过设置数据库/表映射关系,根据传入的定位数据进行匹配,找到正确的库表配置,生成数据访问对象

    以core控制台程序为例

    class Program
        {
            static IServiceProvider provider;
            static Program()
            {
                var services = new ServiceCollection();
                services.AddCRL<DBLocationCreator>();
                services.AddScoped<Code.Sharding.MemberManage>();
    
                provider = services.BuildServiceProvider();
                provider.UseCRL();
            }
    
            static void Main(string[] args)
            {
    
            label1:
                var instance = provider.GetService<Code.Sharding.MemberManage>();
                var data = new Code.Sharding.MemberSharding();
    
                data.Code = "01";
                instance.SetLocation(data);
                var find1 = instance.QueryItem(b => b.Id > 0)?.Name;
                Console.WriteLine($"定位数据输入{data.Code},查询值为{find1}");
    
                data.Code = "02";
                instance.SetLocation(data);
                var find2 = instance.QueryItem(b => b.Id > 0)?.Name;
                Console.WriteLine($"定位数据输入{data.Code},查询值为{find2}");
                Console.ReadLine();
                goto label1;
            }
        }

    上面代码中,通过SetLocation方法传入定位数据Code,通过QueryItem方法查询出数据并打印出来

    通过services.AddCRL<DBLocationCreator>()注入定位配置,DBLocationCreator继承了接口IDBLocationCreator

    这里完全符合core注入规范,可以通过配置或数据库存储动态读取定位设置

     public class DBLocationCreator : IDBLocationCreator
        {
            ISettingConfigBuilder _settingConfigBuilder;
            public DBLocationCreator(ISettingConfigBuilder settingConfigBuilder)
            {
                _settingConfigBuilder = settingConfigBuilder;
            }
    
            public void Init()
            {
                //自定义定位
                _settingConfigBuilder.RegisterLocation<Code.Sharding.MemberSharding>((t, a) =>
                {
                    var tableName = t.TableName;
                    var dbName = a.Code == "02" ? "testdb2" : "testdb";
                    var dataBase = $"Data Source=.;Initial Catalog={dbName};User ID=sa;Password=123";
                    //返回定位库和表名
                    return new CRL.Sharding.Location(dataBase, tableName);
                });
                _settingConfigBuilder.RegisterDBAccessBuild(dbLocation =>
                {
                    var connectionString = "Data Source=.;Initial Catalog=testdb;User ID=sa;Password=123";
                    if (dbLocation.ShardingLocation != null)
                    {
                        connectionString = dbLocation.ShardingLocation.DataBaseSource;
                    }
                    return new CRL.DBAccessBuild(DBType.MSSQL, connectionString);
                });
            }
        }

    在Init方法里,实现了两个操作,通过RegisterLocation定义如何根据定位数据Code,返回不同的库/表

    通过RegisterDBAccessBuild实现数据访问

     对象定义

        public class MemberSharding : CRL.IModel
        {
            [CRL.Attribute.Field(KeepIdentity=true)]//保持插入主键
            public int Id
            {
                get;
                set;
            }
            public string Name
            {
                get;
                set;
            }
            public string Code;
        }
        public class MemberManage : CRL.Sharding.BaseProvider<MemberSharding>
        {
    
        }

    运行测试程序,结果输出为

    上面代码通过自定义定位参数和定位规则,没有任何耦合,调用也很简单,完美达到了预期效果

    测试代码地址:https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest

  • 相关阅读:
    【力扣】11. 盛最多水的容器
    T-SQL 学习笔记 Chapter 6 子查询、表表达式 和排名函数 (一)
    忽然发现只是虚长了年岁,莫名的伤感。
    Gridview 多重表头 (二)
    那些 Cynthia 教我的事 之 PMSec (三)
    那些 Cynthia 教我的事 之 PMSec (二)
    那些 Cynthia 教我的事 之 PMSec (一)
    Gridview 多重表头 (一)
    项目总结之SSI (一)
    项目总结之MIT (一)
  • 原文地址:https://www.cnblogs.com/hubro/p/12693868.html
Copyright © 2011-2022 走看看