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

相关文章
相关标签/搜索