SqlSugar多库/多租户
1、 多库和多租户
如果是接口ISugarClient先看一下标题6,看完在看这儿
1.1 固定多数据库模式
数据库数量是固定的一般在声明的全部加上
//通过ConfigId进行数据库区分var db = new SqlSugarClient(new List<ConnectionConfig>(){ //这儿声名所有上下文都生效 new ConnectionConfig(){ConfigId="0",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true}, new ConnectionConfig(){ConfigId="1",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true }}); //定义实体对应ConfigId ,下面0表示ConfigId为0的数据库 [TenantAttribute("0")]//对应ConfigId public class C1Table { public string Id { get; set; } } //根据特性直接CRUD var list=db.QueryableWithAttr<Order>().ToList();//5.0.9.1 全自动切换库查询var list1=db.AsTenant().QueryableWithAttr<Order>().ToList();//接口需要AsTenant()转成租户var list2=db.Queryable<Order>().AsWithAttr().ToList();//强制名库+表名一般在嵌套或者unionall不能切换库中用db.InsertWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库插入db.UpdateWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库更新db.DeleteableWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库删除//根据特性获取获取dbvar childDb=db.GetConnectionWithAttr<C2Table>();//线程安全用GetConnectionWithAttrScopevar list=childDb.Queryable<Order>().ToList();//手动获取dbvar childA=db.GetConnection("0");//线程安全用GetConnectionScopevar list=childA.Queryable<Order>().ToList();//事务直接用就行,支持回滚(标题3有原理介绍) |
1.2 动态多数据库模式
就是一个用户对应一个库,或一个企业对应一个数据库,通过后台维护用户和数据库的方式
//当前上下文不存在则添加 if(!db.IsAnyConnection(configId)) //添加一个db到当前上下文 (Add部分不线上下文不会共享) db.AddConnection(new ConnectionConfig(){ DbType = SqlSugar.DbType.SqlServer, ConfigId = "1",//设置库的唯一标识 IsAutoCloseConnection = true, ConnectionString = Config.ConnectionString2 }); var currentDb=db.GetConnection(configId);//获取当前上下文存在的db //单例SqlSugarScope中用AddConnection和IsAnyConnection多用户不会相互影响,不会共享 |
Saas分库详解:https://www.donet5.com/Home/Doc?typeId=2403
2、详细用例
2.1 子db操作多库 (推荐)
优点灵活,在库的数据不确定的情况下可以使用,比如SAAS分库结合AddConnection和IsAnyConnection使用
主db
SqlSugarClient或者SqlSugarScope我们称为主db
拥租有租户方法:db.BeginTran(事务)、db.GetConnection(获取子Db)等
在多租户中一般只用来 处理事务、创建子DB和获取子DB
可以用 ISqlSugarClien或者ITenant 接收
ISqlSugarClient.AsTenant() 可以转成 ITenant 调用租户方法
子db
通过租户方法GetConnection出来的我们称为子db,没有租户事务相关方法
我们一般用子db去操作指定ConfigId数据库
可以用 ISqlSugarClient 接收,不能转成租户对象 没有租户方法
//主dbvar db = new SqlSugarClient(new List<ConnectionConfig>(){ new ConnectionConfig(){ConfigId="A",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true}, new ConnectionConfig(){ConfigId="B",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true }, new ConnectionConfig(){ConfigId="C",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true }});//获取子Dbvar childA=db.GetConnection("A");var childB=db.GetConnection("B");var childC=db.GetConnectionScope("C");//线程安全//使用子Db用 childA.Queryable<Order>().ToList(); childB.Queryable<Order>().ToList(); //事务看标题3//线程安全 (推荐) //线程安全 |
2.2 根据特性获取(推荐)
适合一个实体和库是一对一的情况
var db = new SqlSugarClient(new List<ConnectionConfig>(){ new ConnectionConfig(){ConfigId="1",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true}, new ConnectionConfig(){ConfigId="2",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true } });//根据特性获取获取dbvar childDb=db.GetConnectionWithAttr<C2Table>();childDb.Queryable<Order>().ToList();//根据特性直接CRUDvar list=db.QueryableWithAttr<Order>().ToList();//5.0.9.1 全自动切换库查询var list2=db.Queryable<Order>().AsWithAttr().ToList();//强制名库+表名一般在嵌套或者unionall不能切换库中用db.InsertWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库插入db.UpdateWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库更新db.DeleteableWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库删除//如果一个实体对应多个库看SAAS分库文档//事务看标题3 [TenantAttribute("1")]//对应ConfigId public class C1Table { public string Id { get; set; } } [TenantAttribute("2")] public class C2Table { public string Id { get; set; } } |
2.3 通过切换数据库(不推荐)
切换对设计要求过高,很容切了忘记切回来, 特别是一个请求多次切换
var db = new SqlSugarClient(new List<ConnectionConfig>(){ //这儿声名所有上下文都生效 new ConnectionConfig(){ConfigId="0",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true}, new ConnectionConfig(){ConfigId="1",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true }});//使用默认数据库对象db.Deleteable<Order>().ExecuteCommand();//切换主db默认值数据库 ConfigId = 1db.ChangeDatabase("1"); //改变db.的默认数据库db.Deleteable<Order>().ExecuteCommand(); |
注意:只在同一个上下文生效,不同上下文不共享
3、多库事务
支持多库、跨服务器和多种数据库混合使用(老版本db.GetConnection要在事务外声名,然后在事务内用变量)
//开启事务try { db.BeginTran(); //不能是db.Ado.BeginTran db.GetConnection("1").Insertable(new Order() { CreateTime = DateTime.Now, CustomId = 1, Name = "a", Price = 1 }).ExecuteCommand(); db.GetConnection("2").Insertable(new Order() { CreateTime = DateTime.Now, CustomId = 1, Name = "a", Price = 1 }).ExecuteCommand(); //提交事务 db.CommitTran(); //不能是db.ado.CommitTran}catch(Exception ex){ //回滚事务 db.Rollback();} //主db//注入的SqlSugarClient或者SqlSugarScope我们称为主db//子db //通过租户方法GetConnection出来的我们称为子db,用来操作当前数据库,没有租户事务相关方法//主db可以用事务管理多个子db ,也可以使用 GetConnection等租户方法//目前底层是业务执行成功后统一提交事务,业务只要失败全部回滚,统一回滚过程中都有有3次重试回滚//从目前用户使用情况来看,相当稳定几乎没有一例失败的反馈//高安全级别数据:请使用差异日志+Catch(AggregateException ex)进行补偿机质//如果回滚失败会throw new AggregateException |
4、多租户设置AOP
AOP在多租户是不共享的,需要单独设置,满足更多需求,你可以循环添加
//注意: //如果你用的 GetConnectionScope或者 GetConnectionScopeWithAttr AOP也应该用 GetConnectionScope //如果你用的 GetConnection或者 GetConnectionWithAttr AOP也应该用 GetConnectionScope SqlSugarClient Db= new SqlSugarClient(new ConnectionConfig(){ ConnectionString = "连接符字串", DbType = DbType.SqlServer, IsAutoCloseConnection = true}, db=>{ //也可以这里面循环 db.GetConnection("1").Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine("执行1库"+sql); }; db.GetConnection("0").Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine("执行0库"+sql); }; }); |
5、对表进行过滤
db.GetConnection("A").QueryFilter.Add(new TableFilterItem<Order>(it => it.Name.Contains("a"),true)db.GetConnection("B").QueryFilter.Add(new TableFilterItem<Order>(it => it.Name.Contains("a"),true) |
如果要对表进行数据隔离可以看 查询过滤器的例子
https://www.donet5.com/Home/Doc?typeId=1205
6、ISugarClient使用多租户
问题:Db.GetConnection点不出来,出现这种情况一般是用的接口对象ISqlSugarClient
解决方案: Db.AsTenant().GetConnection(1)
原理如下:
ISqlSugarClient和SqlSugarClient不同,ISqlSugarClient不包含租户方法,原因如下
SqlSugarClient : ISqlSugarClient, ITenant //ISqlSugarClient和ITenant是平行关系,没有租户方法 |
我们可以通过自带转换实现
ISqlSugarClient db= 注入db ;db.AsTenant().BeginTran();db.AsTenant().CommitTran();db.AsTenant().RollbackTran();db.AsTenant().GetConnection(1)db.AsTenant().IsAnyConnection(1)//低版本 (db as ITenant).BeginTran() |
SqlSugar多库/多租户的更多相关文章
- FreeSql 将 Saas 租户方案精简到极致[.NET ORM SAAS]
什么是多租户 维基百科:"软件多租户是指一种软件架构,在这种软件架构中,软件的一个实例运行在服务器上并且为多个租户服务".一个租户是一组共享该软件实例特定权限的用户.有了多租户架构 ...
- FreeSql 将 Saas 租户方案精简到极致[.NET ORM]
什么是多租户 维基百科:"软件多租户是指一种软件架构,在这种软件架构中,软件的一个实例运行在服务器上并且为多个租户服务".一个租户是一组共享该软件实例特定权限的用户.有了多租户架构 ...
- .NET 6 跨服务器联表查询
一.大家是否有这个需求 1.跨品种查询 :比如 MYSQL和一个SQLSERVER进行联表查询 ,或者SQLITE和MYSQL进行联表查询 2.跨服务器查询 : A服务器和B服务器查询 如果想同时支持 ...
- Oracle 12c 多租户 CDB 与 PDB 级别 expdb 与 impdb(表、用户、全库)
Oracle 数据库 12 c 多租户下,如何在容器数据库 (CDB) 和可插拔数据库 (PDB) 中使用 expdb 与 impdp (数据泵) 呢? 我们一起探讨下PDB 下进行表级,用户级别,全 ...
- ORM 创新解放劳动力 -SqlSugar 新功能介绍
介绍 SqlSugar是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,Github star数仅次于EF 和 Dapper 优点: 简单易用.功能齐全.高性能.轻量级.服务齐 ...
- .NET SAAS 架构与设计 -SqlSugar ORM
1.数据库设计 常用的Saas分库分为2种类型的库 1.1 基础信息库 主要存组织架构 .权限.字典.用户等 公共信息 性能优化:因为基础信息库是共享的,所以我们可以使用 读写分离,或者二级缓存来进行 ...
- .NET 开源SqlServer ORM框架 SqlSugar 3.0 API
3.1.x ,将作为3.X系统的最后一个版本,下面将会开发 全新的功能 更新列表:https://github.com/sunkaixuan/SqlSugar/releases 优点: SqlSuga ...
- 【Network】OVS、VXLAN/GRE、OVN等 实现 Docker/Kubernetes 网络的多租户隔离
多租户隔离 DragonFlow与OVN | SDNLAB | 专注网络创新技术 Neutron社区每周记(6.25~7.6)| OVS将加入Linux基金会?OVN或抛弃ovsdb? | Unite ...
- 【开源框架】SqlSugarRepository 全库ORM 正式发布
SqlSugarRepository.dll 全库开发框架支持 四种数据库:SqlServer. MySql .Oracle和Sqlite. SqlSugarRepository是为全库开发而生的OR ...
- SqlSugar ORM已经支持读写分离
目前只有MYSQL版 3.5.2.9 支持,其库版本12月3号更新该功能 用例讲解 using (var db = new SqlSugarClient("主连接字符串", &qu ...
随机推荐
- Filebeat的安装和使用(Windows)
Filebeat是什么 1.Filebeat是什么?Filebeat是用于转发和集中日志数据的轻量级传送工具. Filebeat监视用户指定的日志文件或位置,收集日志事件,并将日志数据转发到Elast ...
- Django中安装websocket
完整代码: https://gitee.com/mom925/django-system项目结构: 先安装所需库: pip install channels下面将websocket作为插件一样的只需要 ...
- Q查询进阶操作 ORM查询优化 only与defer select_related与prefetch_related ORM事务 ORM常用字段类型 ORM常用字段参数
目录 Q查询进阶操作 children.append 图书查询功能 ORM查询优化 惰性查询 自动分页 limit only与defer only defer select_related与prefe ...
- MP4 视频“只闻其声,不见其人”,是怎么回事呢?
艾瑞巴蒂大家好,我二狗子又来啦!这段时间关于疫情的好消息不断,各个地区的疫情都得到了有效的控制,做到了新增病例个位数增长甚至连续多天零增长!这不,二狗子也终于可以出村回到大城市上班啦!由于要坐很久的火 ...
- Go--记录下踩map的坑
这两天新调个接口的时候,一直提示签名错误,但所需的时间,工号,token都是对的,完全没有头绪,卡了两天后,终于找到原因了 原因是我的校验信息,是要将时间,工号,token封装在一起成字符串,然后用m ...
- SpringBoot 项目实战 | 瑞吉外卖 优化篇 Day01
该系列将记录一份完整的实战项目的完成过程,该篇属于优化篇第一天,主要负责完成缓存优化问题 案例来自B站黑马程序员Java项目实战<瑞吉外卖>,请结合课程资料阅读以下内容 该篇我们将完成以下 ...
- node开发概述
一.Node开发概述 1. 为什么要学习服务器端开发 能够与后端程序员更加紧密的配合 网站业务逻辑前置,学习前端技术需要后端技术支撑(ajax) 扩宽知识视野,能够站在更高的角度审视整个项目 2. 服 ...
- distributor和gateway联合实现出中继的负载均衡+故障转移
概述 freeswitch是一款简单好用的VOIP开源软交换平台. 在之前的文章,我们介绍过distributor模块实现多线路分发的配置方法,但是当线路发生故障时,distributor并不会自动跳 ...
- C#设计模式08——桥接模式的写法
什么是C#桥接模式?桥接模式是一种结构型设计模式,它可以将抽象部分与实现部分分离,使它们可以独立地变化.这种模式通过将实现细节从抽象类中分离出来,从而让它们可以根据需要独立变化. 为什么要使用C#桥接 ...
- 每天学五分钟 Liunx 0010 | 软件篇: RPM 和 YUM
1. RPM RPM(RedHat Package Manager),顾名思义是 RedHat 的软件包管理器.它遵循 GPL 规则且功能强大好用,从而逐渐运用到其它 Liunx 发行版中,包括 Fe ...