EF多租戶實例:快速實現分庫分表

前言

來到這篇隨筆,咱們繼續演示如何實現EF多租戶。html

今天主要是演示多租戶下的變形,爲下圖所示mysql

 

 

實施

項目結構

此次咱們的示例項目進行了精簡,僅有一個API項目,直接包含全部代碼。git

其中Controller,StoreContext,Entity都徹底和以往的示例如出一轍,這裏就再也不過多介紹了。github

具備主要區別的是 CombinedConnectionGenerator 和 Startup sql

 

 

代碼解釋

1. 首先要關注的是做爲入口的 Startup ,仍是一個套路,分別在 ConfigureService 註冊EF多租戶, 在 Configure 配置中間件。數據庫

ConfigureService 仍是一向的簡單。可是注意這裏使用的 AddMySqlPerTable 這個模式。app

在混合的模式中,須要已最小的單元做爲服務註冊。因爲此次是數據庫和數據表混合模式,因此須要用數據表來註冊。ui

1 public void ConfigureServices(IServiceCollection services) 2 { 3     services.AddScoped<IConnectionGenerator, CombindedConnectionGenerator>(); 4     services.AddMySqlPerTable<StoreDbContext>(settings =>
5  { 6         settings.ConnectionPrefix = "mysql_"; 7  }); 8  services.AddControllers(); 9 }

Configure的使用更加簡單,只須要添加中間件 TenantInfoMiddleware 便可。this

 1 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  2 {  3     if (env.IsDevelopment())  4  {  5  app.UseDeveloperExceptionPage();  6  }  7 
 8     app.UseMiddleware<TenantInfoMiddleware>();  9 
10  app.UseRouting(); 11 
12     app.UseEndpoints(endpoints =>
13  { 14  endpoints.MapControllers(); 15  }); 16 }

 

2. 此次須要本身實現 ConnectionGenerator spa

關鍵點有2個,

第一個關鍵點,因爲咱們的類庫是同時支持多個DbContext的,因此須要有TenantKey去區分。因爲有種特殊狀況,須要一個 ConnectionGenerator 同時支持多個 DbContext ,因此這裏提供了 MatchTenantKey 方法做爲補充的判斷依據。

能夠看出來,咱們這裏TenantKey 爲空,因此通常都不會匹配中。示例中徹底是依靠 MatchTenantKey 來作匹配的。

第二個關鍵點,GetConnection 做爲最主要的邏輯方法,經過對TenantName 的數字部分進行取模,最終拼接處ConnectionString的鍵值

而且經過 Configuration 獲取鏈接字符串

 1 public class CombindedConnectionGenerator : IConnectionGenerator  2 {  3     private readonly IConfiguration configuration;  4     public string TenantKey => "";  5 
 6     public CombindedConnectionGenerator(IConfiguration configuration)  7  {  8         this.configuration = configuration;  9  } 10 
11 
12     public string GetConnection(TenantOption option, TenantInfo tenantInfo) 13  { 14         var span = tenantInfo.Name.AsSpan(); 15         if (span.Length > 4 && int.TryParse(span[5].ToString(), out var number)) 16  { 17             return configuration.GetConnectionString($"{option.ConnectionPrefix}container{number % 2 + 1}"); 18  } 19         throw new NotSupportedException("tenant invalid"); 20  } 21 
22     public bool MatchTenantKey(string tenantKey) 23  { 24         return true; 25  } 26 }

 

 

檢驗結果

檢驗結果我以爲已經沒有必要的,都是一樣的套路,主要的區別是,以前的只有一個數據庫,或者多個數據庫

此次的混合模式,主要是一個數據庫做爲一個container,裏面能夠同時包含多個product數據表。

Container1

 

Container2

 

 

 

總結

其實這個例子也是很是簡單的,目的是讓每一個人都能快速應用複雜的分庫分表

下一篇文章將會經過多租戶實現讀寫分離。

 

關於這個文章的全部代碼,已經同步到Github

https://github.com/woailibain/kiwiho.EFcore.MultiTenant/tree/master/example/mix_mode/kiwiho.EFcore.MultiTenant.MixMode

 

原文出處:https://www.cnblogs.com/woailibian/p/12632019.html

相關文章
相關標籤/搜索