如果是接口ISugarClient先看一下标题6,看完在看这儿
数据库数量是固定的一般在声明的全部加上
//通过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<User>().ToList();//5.0.9.1 全自动切换库查询 var list=db.AsTenant().QueryableWithAttr<User>().ToList();//接口需要AsTenant()转成租户 var list=db.Queryable<User>().AsWithAttr().ToList();//强制将库名+表名输出到sql实现跨库(union all需要) db.InsertableWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库插入 db.UpdateableWithAttr(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有原理介绍)
就是一个用户对应一个库,或一个企业对应一个数据库,通过后台维护用户和数据库的方式
//当前上下文不存在则添加 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 //和主库AOP不共享需 //currentDb.Aop.xxx //单例SqlSugarScope中用AddConnection和IsAnyConnection多用户不会相互影响,不会共享
Saas分库详解:https://www.donet5.com/Home/Doc?typeId=2403
优点灵活,在库的数据不确定的情况下可以使用,比如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 //线程安全 (推荐) //线程安全
适合一个实体和库是一对一的情况
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.InsertableWithAttr(list).ExecuteCommand() ;//5.0.9.1 全自动切换库插入 db.UpdateableWithAttr(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; } }
切换对设计要求过高,很容切了忘记切回来, 特别是一个请求多次切换
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();
注意:只在同一个上下文生效,不同上下文不共享
支持多库、跨服务器和多种数据库混合使用(老版本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
AOP在多租户是不共享的,需要单独设置,满足更多需求,你可以循环添加
//注意: //如果你用的 GetConnectionScope或者 GetConnectionScopeWithAttr AOP也应该用 GetConnectionScope //如果你用的 GetConnection或者 GetConnectionWithAttr AOP也应该用 GetConnectionScope var configs = new List<ConnectionConfig>(){ new ConnectionConfig(){ ConfigId="1",ConnectionString = "...", DbType = DbType.SqlServer,IsAutoCloseConnection = true }, new ConnectionConfig(){ ConfigId="2",ConnectionString = "...", DbType = DbType.SqlServer,IsAutoCloseConnection = true } }; SqlSugarClient Db = new SqlSugarClient(configs, db => { foreach (var item in configs) { //也可以这里面循环 db.GetConnection(item.ConfigId).Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine("执行1库" + sql); }; } }); });
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
问题: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()
2016 © donet5.comApache Licence 2.0