詳解在.net core中完美解決多租戶分庫分表的問題
前幾天有人想做一個多租戶的平臺,每個租戶一個庫,可以進(jìn)行水平擴(kuò)展,應(yīng)用端根據(jù)登錄信息,切換到不同的租戶庫
計劃用ef core實現(xiàn),他們說做不出來,需要動態(tài)創(chuàng)建dbContext,不好實現(xiàn)
然而這個使用CRL很輕松就能解決了
以下為演示數(shù)據(jù)庫,有兩個庫testdb和testdb2,查詢結(jié)果如下
目標(biāo):
根據(jù)傳入登錄信息連不不同的庫,查詢返回結(jié)果,如登錄人為01,返回d1.default,登錄人為02 返回 d2.default
實際上這個需求就是分庫分表的實現(xiàn),通過設(shè)置數(shù)據(jù)庫/表映射關(guān)系,根據(jù)傳入的定位數(shù)據(jù)進(jìn)行匹配,找到正確的庫表配置,生成數(shù)據(jù)訪問對象
以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($"定位數(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; } }
上面代碼中,通過SetLocation方法傳入定位數(shù)據(jù)Code,通過QueryItem方法查詢出數(shù)據(jù)并打印出來
通過services.AddCRL<DBLocationCreator>()注入定位配置,DBLocationCreator繼承了接口IDBLocationCreator
這里完全符合core注入規(guī)范,可以通過配置或數(shù)據(jù)庫存儲動態(tài)讀取定位設(shè)置
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方法里,實現(xiàn)了兩個操作,通過RegisterLocation定義如何根據(jù)定位數(shù)據(jù)Code,返回不同的庫/表
通過RegisterDBAccessBuild實現(xiàn)數(shù)據(jù)訪問
運(yùn)行測試程序,結(jié)果輸出為
上面代碼通過自定義定位參數(shù)和定位規(guī)則,沒有任何耦合,調(diào)用也很簡單,完美達(dá)到了預(yù)期效果
測試代碼地址:https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest
到此這篇關(guān)于詳解在.net core中完美解決多租戶分庫分表的問題的文章就介紹到這了,更多相關(guān).net core多租戶分庫分表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
.NET 6開發(fā)TodoList應(yīng)用之實現(xiàn)ActionFilter
Filter在.NET Web API項目開發(fā)中也是很重要的一個概念,它運(yùn)行在執(zhí)行MVC響應(yīng)的Pipeline中執(zhí)行,允許我們將一些可以在多個Action之間重用的邏輯抽取出來集中管理。本文將詳細(xì)介紹一下.NET 6如何實現(xiàn)ActionFilter,感興趣的可以學(xué)習(xí)一下2021-12-12ASP.NET Mvc開發(fā)之刪除修改數(shù)據(jù)
這篇文章主要介紹了ASP.NET Mvc開發(fā)中的刪除修改數(shù)據(jù)功能,感興趣的小伙伴們可以參考一下2016-03-03.NET實現(xiàn)ChatGPT的Stream傳輸?shù)倪^程
這篇文章主要介紹了.NET如何實現(xiàn)ChatGPT的Stream傳輸,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07asp.net實現(xiàn)取消頁面表單內(nèi)文本輸入框Enter響應(yīng)的方法
這篇文章主要介紹了asp.net實現(xiàn)取消頁面表單內(nèi)文本輸入框Enter響應(yīng)的方法,結(jié)合實例形式分析了asp.net文本框Enter響應(yīng)的原理與取消Enter響應(yīng)的相關(guān)實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11