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 全自动切换库删除
//根据特性获取获取db
var childDb=db.GetConnectionWithAttr<C2Table>(); //线程安全用GetConnectionWithAttrScope
var list=childDb.Queryable<Order>().ToList();
//手动获取db
var childA=db.GetConnection( "0" ); //线程安全用GetConnectionScope
var 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 接收,不能转成租户对象 没有租户方法
//主db
var 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 }
});
//获取子Db
var 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 }
});
//根据特性获取获取db
var childDb=db.GetConnectionWithAttr<C2Table>();
childDb.Queryable<Order>().ToList();
//根据特性直接CRUD
var 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 = 1
db.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()
|
标签:租户,GetConnection,db,DbType,var,new,SqlSugar,多库 From: https://www.cnblogs.com/yswenli/p/17967850