前几天有人想做一个多租户的平台,每个租户一个库,可以进行水平扩展,应用端根据登录信息,切换到不同的租户库
计划用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)"定位数据输入{data.Code},查询值为{find1}"); data.Code = "02"; instance.SetLocation(data); var find2 = instance.QueryItem(b => b.Id > 0)"定位数据输入{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实现数据访问
运行测试程序,结果输出为
上面代码通过自定义定位参数和定位规则,没有任何耦合,调用也很简单,完美达到了预期效果
测试代码地址:https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。