前言

来到这篇随笔,我们继续演示如何实现EF多租户。

今天主要是演示多租户下的变形,为下图所示

实施

项目结构

这次我们的示例项目进行了精简,仅有一个API项目,直接包含所有代码。

其中Controller,StoreContext,Entity都完全和以往的示例一模一样,这里就不再过多介绍了。

具有主要区别的是 CombinedConnectionGenerator 和 Startup

代码解释

1. 首先要关注的是作为入口的 Startup ,还是一个套路,分别在 ConfigureService 注册EF多租户, 在 Configure 配置中间件。

ConfigureService 还是一贯的简单。但是注意这里使用的 AddMySqlPerTable 这个模式。

在混合的模式中,需要已最小的单元作为服务注册。由于这次是数据库和数据表混合模式,所以需要用数据表来注册。

 public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IConnectionGenerator, CombindedConnectionGenerator>();
services.AddMySqlPerTable<StoreDbContext>(settings =>
{
settings.ConnectionPrefix = "mysql_";
});
services.AddControllers();
}

Configure的使用更加简单,只需要添加中间件 TenantInfoMiddleware 即可。

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMiddleware<TenantInfoMiddleware>(); app.UseRouting(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

2. 这次需要自己实现 ConnectionGenerator

关键点有2个,

第一个关键点,由于我们的类库是同时支持多个DbContext的,所以需要有TenantKey去区分。由于有种特殊情况,需要一个 ConnectionGenerator 同时支持多个 DbContext ,所以这里提供了 MatchTenantKey 方法作为补充的判断依据。

可以看出来,我们这里TenantKey 为空,所以一般都不会匹配中。示例中完全是依靠 MatchTenantKey 来做匹配的。

第二个关键点,GetConnection 作为最主要的逻辑方法,通过对TenantName 的数字部分进行取模,最终拼接处ConnectionString的键值

并且通过 Configuration 获取连接字符串

 public class CombindedConnectionGenerator : IConnectionGenerator
{
private readonly IConfiguration configuration;
public string TenantKey => ""; public CombindedConnectionGenerator(IConfiguration configuration)
{
this.configuration = configuration;
} public string GetConnection(TenantOption option, TenantInfo tenantInfo)
{
var span = tenantInfo.Name.AsSpan();
if (span.Length > && int.TryParse(span[].ToString(), out var number))
{
return configuration.GetConnectionString($"{option.ConnectionPrefix}container{number % 2 + 1}");
}
throw new NotSupportedException("tenant invalid");
} public bool MatchTenantKey(string tenantKey)
{
return true;
}
}

检验结果

检验结果我觉得已经没有必要的,都是同样的套路,主要的区别是,之前的只有一个数据库,或者多个数据库

这次的混合模式,主要是一个数据库作为一个container,里面可以同时包含多个product数据表。

Container1

Container2

总结

其实这个例子也是非常简单的,目的是让每个人都能快速应用复杂的分库分表

下一篇文章将会通过多租户实现读写分离。

关于这个文章的所有代码,已经同步到Github

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

EF多租户实例:快速实现分库分表的更多相关文章

  1. 一文快速入门分库分表中间件 Sharding-JDBC (必修课)

    书接上文 <一文快速入门分库分表(必修课)>,这篇拖了好长的时间,本来计划在一周前就该写完的,结果家庭内部突然人事调整,领导层进行权利交接,随之宣布我正式当爹,紧接着家庭地位滑落至第三名, ...

  2. sharding-jdbc 分库分表的 4种分片策略,还蛮简单的

    上文<快速入门分库分表中间件 Sharding-JDBC (必修课)>中介绍了 sharding-jdbc 的基础概念,还搭建了一个简单的数据分片案例,但实际开发场景中要远比这复杂的多,我 ...

  3. 在.net core中完美解决多租户分库分表的问题

    前几天有人想做一个多租户的平台,每个租户一个库,可以进行水平扩展,应用端根据登录信息,切换到不同的租户库 计划用ef core实现,他们说做不出来,需要动态创建dbContext,不好实现 然而这个使 ...

  4. EasySharding.EFCore 如何设计使用一套代码完成的EFCore Migration 构建Saas系统多租户不同业务需求且满足租户自定义分库分表、数据迁移能力?

    下面用一篇文章来完成这些事情 多租户系统的设计单纯的来说业务,一套Saas多租户的系统,面临很多业务复杂性,不同的租户存在不同的业务需求,大部分相同的表结构,那么如何使用EFCore来完成这样的设计呢 ...

  5. CRL快速开发框架系列教程十一(大数据分库分表解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  6. sharding-jdbc之——分库分表实例

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79368021 一.概述 之前,我们介绍了利用Mycat进行分库分表操作,Mycat ...

  7. springboot+mybatisplus+sharding-jdbc分库分表实例

    项目实践 现在Java项目使用mybatis多一些,所以我也做了一个springboot+mybatisplus+sharding-jdbc分库分表项目例子分享给大家. 要是用的springboot+ ...

  8. Mycat读写分离、主从切换、分库分表的操作记录

    系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...

  9. mysql分库分表那些事

    为什么使用分库分表? 如下内容,引用自 Sharding Sphere 的文档,写的很大气. <ShardingSphere > 概念 & 功能 > 数据分片> 传统的 ...

随机推荐

  1. Python基本小程序

    目录 Python基本小程序 一.筛选从1-100所有的奇数 二.筛选从0-100所有的偶数 三.求1-100之间所有的偶数和,奇数和 四.三个数由小到大输出 五.四个数字重复数字的三位数 Pytho ...

  2. 7-4 jmu-python-判断是否构成三角形 (10 分)

    7-4 jmu-python-判断是否构成三角形 (10 分)   输入三角形的三边,判断是否能构成三角形.若能构成输出yes,否则输出no. 输入格式: 在一行中直接输入3个整数,3个整数之间各用一 ...

  3. 蚂蚁金服开源 | 可视化图形语法G2 3.3 琢磨

    G2 是蚂蚁金服数据可视化解决方案 AntV 的一个子产品,是一套数据驱动的.高交互的可视化图形语法. 经过两个多月密锣紧鼓的开发,400+次提交,G2 3.3版本今天终于和大家见面了.自上次3.2版 ...

  4. npm发布包的那些事

    npm发包的那些事 最近一直在研习关于node的知识,发布包虽然是最基础的一点,但由于一些地方的不注意很容易发生错误,我整理了我可能出现过的一些发布包的过程中的一些error,现在分享给大家: 正确的 ...

  5. JZOJ 5258. 友好数对 (Standard IO)

    5258. 友好数对 (Standard IO) Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits Description I ...

  6. Swfit 属性与汇编分析inout本质

    今天将讲述Swift属性以及剖析inout的本质, 如有兴趣可点击关注,以后会定期更新更有料的博客!!! 一.属性 Swift中跟实例相关的属性可以分为2大类 存储属性(Stored property ...

  7. seo搜索优化技巧01-seo外链怎么发?

    在seo搜索优化中,seo外链的作用并没有早期的作用大了.可是高质量的外链对关键词的排名还是很重要的.星辉信息科技对seo外链怎么发以及seo外链建设中的注意点进行阐述. SEO外链如何做 SEO高质 ...

  8. OpenWrt tcpdump 抓包

    路由器用的是 网件的 4300 刷的是石像鬼双固件 1, 安装支持库opkg updateopkg install libpcapopkg install tcpdump 2, 设置条件开始捕获tcp ...

  9. 使用StreamHttpResponse和FileResponse下载文件的注意事项及文件私有化

    为什么需要编写下载视图方法? 你或许知道,我们上传的文件默认放在media文件夹中的,且Django会为每个上传的静态文件分配一个静态url.在模板中,你可以使用{{ mymodel.file.url ...

  10. golang bufio.NewScarme

    // dup1 输出标准输入中出现次数大于1的行,前面是次数 package main import ( "bufio" "fmt" "os" ...