前言

来到这篇随笔,我们继续演示如何实现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. ZYNQ自定义AXI总线IP应用——PWM实现呼吸灯效果

    一.前言 在实时性要求较高的场合中,CPU软件执行的方式显然不能满足需求,这时需要硬件逻辑实现部分功能.要想使自定义IP核被CPU访问,就必须带有总线接口.ZYNQ采用AXI BUS实现PS和PL之间 ...

  2. 提权篇之简单介绍和exp利用过程

    正文开始.... 提权的方法有很多种,因为一开始我入门的时候是看的小迪的网络教程,当然也推荐大家去看小迪的教程,或者直接小迪的实地培训班.这个可没什么利益关系,我认识他,他可不认识我,,但是我是在网上 ...

  3. Centos +Docker 安装及仓库使用概述

    ​1. Linux 系统学习Docker安装篇 这里我使用的Centos系统 安装Docker yum命令说明 即Yellowdog Update Modifier,是一种基于rpm的包管理工具 yu ...

  4. js变量提升、函数提升详解

    一.变量提升是指将变量声明提升到它所在作用域的最开始部分 console.log(a) // 为什么会出现以上的结果,是因为js的变量提升,将a变量的声明提升到全局作用域的最上面部分,实际代码如下: ...

  5. JS基础入门篇(十八)—日期对象

    1.日期对象 日期对象: 通过new Date()就能创建一个日期对象,这个对象中有当前系统时间的所有详细信息. 以下代码可以获取当前时间: <script> var t = new Da ...

  6. Xcode辅助工具之热重载插件利器

    该博客首发于github.io 2018-06-13 13:43:44 文章最新修改于: 2019-03-31 13:47:20 昨天刚刚看完iOSTips微信公众号推送的文章, Injection: ...

  7. 第八章、小节二vuex

    a.用vuex首先先安装vuex npm install vuex --save b.在src目录下创建store文件夹,在store中创建index.js存放各个状态 c.在一个模块化的打包系统中, ...

  8. Linux环境下安装MySQL 5.7.28

    先进入MySQL官网: www.mysql.com 去下载安装包 进入DOWNLOADS选项,点击MySQL Community (GPL) Downloads. 点击进入MySQL Communit ...

  9. ElasticSearch 6.2.4 实践

    参考资料 ElasticSearch 官网 ElasticSearch,Kibana,Asp.net Core with docker 示例 阮一峰 ElasticSearch 基础概念 索引(ind ...

  10. postgresql自增字段初始值的设定

    在实际开发中会有这样的需求,想要自己设置表中自增字段的初始值. 比如:有一个your_table表中有一个自增字段id,我们知道,插入数据后,默认是从1开始自增的. 但是假如现在有一个需求,是要求id ...