在.net core中完美解决多租户分库分表的问题
前几天有人想做一个多租户的平台,每个租户一个库,可以进行水平扩展,应用端根据登录信息,切换到不同的租户库
计划用ef core实现,他们说做不出来,需要动态创建dbContext,不好实现
然而这个使用CRL很轻松就能解决了
以下为演示数据库,有两个库testdb和testdb2,查询结果如下


目标:
根据传入登录信息连不不同的库,查询返回结果,如登录人为01,返回d1.default,登录人为02 返回 d2.default
实际上这个需求就是分库分表的实现,通过设置数据库/表映射关系,根据传入的定位数据进行匹配,找到正确的库表配置,生成数据访问对象
以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 = "";
instance.SetLocation(data);
var find1 = instance.QueryItem(b => b.Id > )?.Name;
Console.WriteLine($"定位数据输入{data.Code},查询值为{find1}"); data.Code = "";
instance.SetLocation(data);
var find2 = instance.QueryItem(b => b.Id > )?.Name;
Console.WriteLine($"定位数据输入{data.Code},查询值为{find2}");
Console.ReadLine();
goto label1;
}
}
上面代码中,通过SetLocation方法传入定位数据Code,通过QueryItem方法查询出数据并打印出来
通过services.AddCRL<DBLocationCreator>()注入定位配置,DBLocationCreator继承了接口IDBLocationCreator
这里完全符合core注入规范,可以通过配置或数据库存储动态读取定位设置
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 == "" ? "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方法里,实现了两个操作,通过RegisterLocation定义如何根据定位数据Code,返回不同的库/表
通过RegisterDBAccessBuild实现数据访问
对象定义
public class MemberSharding : CRL.IModel
{
[CRL.Attribute.Field(KeepIdentity=true)]//保持插入主键
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
public string Code;
}
public class MemberManage : CRL.Sharding.BaseProvider<MemberSharding>
{ }
运行测试程序,结果输出为

上面代码通过自定义定位参数和定位规则,没有任何耦合,调用也很简单,完美达到了预期效果
测试代码地址:https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest
在.net core中完美解决多租户分库分表的问题的更多相关文章
- [.NET Core]ASP.NET Core中如何解决接收表单时的不支持的媒体类型(HTTP 415 Unsupported Media Type)错误呢?
[.NET Core]ASP.NET Core中如何解决接收表单时的不支持的媒体类型(HTTP 415 Unsupported Media Type)错误呢? 在ASP.NET Core应用程序中,接 ...
- EasySharding.EFCore 如何设计使用一套代码完成的EFCore Migration 构建Saas系统多租户不同业务需求且满足租户自定义分库分表、数据迁移能力?
下面用一篇文章来完成这些事情 多租户系统的设计单纯的来说业务,一套Saas多租户的系统,面临很多业务复杂性,不同的租户存在不同的业务需求,大部分相同的表结构,那么如何使用EFCore来完成这样的设计呢 ...
- 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)
原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_ ...
- 超实用的mysql分库分表策略,轻松解决亿级数据问题
一.分库分表的背景 在数据爆炸的年代,单表数据达到千万级别,甚至过亿的量,都是很常见的情景.这时候再对数据库进行操作就是非常吃力的事情了,select个半天都出不来数据,这时候业务已经难以维系.不得已 ...
- 分布式中的分库分表之后,ID 主键如何处理?
面试题 分库分表之后,id 主键如何处理?(唯一性,排序等) 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 开始累加,那肯定 ...
- EF多租户实例:快速实现分库分表
前言 来到这篇随笔,我们继续演示如何实现EF多租户. 今天主要是演示多租户下的变形,为下图所示 实施 项目结构 这次我们的示例项目进行了精简,仅有一个API项目,直接包含所有代码. 其中Control ...
- Mysql中的分库分表
mysql中的分库分表分库:减少并发问题分表:降低了分布式事务分表 1.垂直分表 把其中的不常用的基础信息提取出来,放到一个表中通过id进行关联.降低表的大小来控制性能,但是这种方式没有解决高数据量带 ...
- .net core 基于Dapper 的分库分表开源框架(core-data)
一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率: 在数据库的数据日积月累的积累下,业务 ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统 | 前言
介绍 大家好我是初久,一名从业4年的.Net开发攻城狮,从今天开始我会和大家一起对企业开发中常用的技术进行分享,一方面督促自己学习,一方面也希望大家可以给我指点出更好的方案,我们一起进步. 项目背景 ...
随机推荐
- Android平台接入OneNET
1. OneNET简介 中国移动物联网开放平台是由中国移动打造的PaaS物联网开放平台. 平台能够帮助开发者轻松实现设备接入与设备连接,提供综合性的物联网解决方案,实现物联网设备的数据获取,数据存储, ...
- 基于kylinTOP工具的HTTP2压力测试
1.HTTP协议概述 说到http,那就应该先了解一下http协议的发展历史.关于http协议的历史,可以参考阮一峰老师的这篇博客文章HTTP 协议入门,里面介绍的比较详细了.简单来说http先后存在 ...
- 曹工说Spring Boot源码(24)-- Spring注解扫描的瑞士军刀,asm技术实战(上)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- NIO的原理和文件读入读出及图片拷贝的使用
1.NIO的简介 java.nio 全称 java non-blocking IO 是jdk1.4之后出现的 New IO 为所有的原始类型(boolean除外)提供了缓存 ...
- gRPC (1):入门及服务端创建和调用原理
1. RPC 入门 1.1 RPC 框架原理 RPC 框架的目标就是让远程服务调用更加简单.透明,RPC 框架负责屏蔽底层的传输方式(TCP 或者 UDP).序列化方式(XML/Json/ 二进制)和 ...
- python-模块的发布和安装
当我们 import python 模块时,默认先在当前路径搜索,如果当前路径找不到目标模块,python会到安装目录找,还找不到则抛出异常. 如果我们想让自己写的模块,能跟系统自带模块一样,在任何地 ...
- Anaconda常用命令收藏----后期还会更新
一.更换jupyter notobook的打开目录 一般载在安装好Anaconda的时候,打开jupyter指向的目录一般是系统的根目录,如C:\Users\25282,但是这样的话对C盘是个不小的负 ...
- 插入排序与Shell排序
ElementType ShellSort( ElementType A[], int N ) { ;h>;h/=){ for(int i=h;i<N;i++){ ElementType ...
- 【笔记3-31】Python语言基础-列表list
列表list my_list = [1, 2, 3, 4, 5] 索引index my_list[0] 获取列表长度 len(my_list) 切片 [起始:结束:步长] my_list[1:3:2] ...
- coding++ :JS-判断当前是否是IE浏览器,并返回时IE几?
IEVersion(); function IEVersion() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 var is ...