前幾天有人想做一個(gè)多租戶的平臺(tái),每個(gè)租戶一個(gè)庫(kù),可以進(jìn)行水平擴(kuò)展,應(yīng)用端根據(jù)登錄信息,切換到不同的租戶庫(kù)
計(jì)劃用ef core實(shí)現(xiàn),他們說(shuō)做不出來(lái),需要?jiǎng)討B(tài)創(chuàng)建dbContext,不好實(shí)現(xiàn)
然而這個(gè)使用CRL很輕松就能解決了
以下為演示數(shù)據(jù)庫(kù),有兩個(gè)庫(kù)testdb和testdb2,查詢結(jié)果如下
目標(biāo):
根據(jù)傳入登錄信息連不不同的庫(kù),查詢返回結(jié)果,如登錄人為01,返回d1.default,登錄人為02 返回 d2.default
實(shí)際上這個(gè)需求就是分庫(kù)分表的實(shí)現(xiàn),通過(guò)設(shè)置數(shù)據(jù)庫(kù)/表映射關(guān)系,根據(jù)傳入的定位數(shù)據(jù)進(jìn)行匹配,找到正確的庫(kù)表配置,生成數(shù)據(jù)訪問(wèn)對(duì)象
以core控制臺(tái)程序?yàn)槔?/p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
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($ "定位數(shù)據(jù)輸入{data.Code},查詢值為{find1}" ); data.Code = "02" ; instance.SetLocation(data); var find2 = instance.QueryItem(b => b.Id > 0)?.Name; Console.WriteLine($ "定位數(shù)據(jù)輸入{data.Code},查詢值為{find2}" ); Console.ReadLine(); goto label1; } } |
上面代碼中,通過(guò)SetLocation方法傳入定位數(shù)據(jù)Code,通過(guò)QueryItem方法查詢出數(shù)據(jù)并打印出來(lái)
通過(guò)services.AddCRL<DBLocationCreator>()注入定位配置,DBLocationCreator繼承了接口IDBLocationCreator
這里完全符合core注入規(guī)范,可以通過(guò)配置或數(shù)據(jù)庫(kù)存儲(chǔ)動(dòng)態(tài)讀取定位設(shè)置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
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" ; / / 返回定位庫(kù)和表名 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方法里,實(shí)現(xiàn)了兩個(gè)操作,通過(guò)RegisterLocation定義如何根據(jù)定位數(shù)據(jù)Code,返回不同的庫(kù)/表
通過(guò)RegisterDBAccessBuild實(shí)現(xiàn)數(shù)據(jù)訪問(wèn)
運(yùn)行測(cè)試程序,結(jié)果輸出為
上面代碼通過(guò)自定義定位參數(shù)和定位規(guī)則,沒(méi)有任何耦合,調(diào)用也很簡(jiǎn)單,完美達(dá)到了預(yù)期效果
測(cè)試代碼地址:https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest
到此這篇關(guān)于詳解在.net core中完美解決多租戶分庫(kù)分表的問(wèn)題的文章就介紹到這了,更多相關(guān).net core多租戶分庫(kù)分表內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://www.cnblogs.com/hubro/p/12693868.html