首页 > 数据库 >SqlSugar多库/多租户

SqlSugar多库/多租户

时间:2024-01-16 15:57:29浏览次数:21  
标签:租户 GetConnection db DbType var new 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 { getset; }  }         //根据特性直接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 { getset; }   }        [TenantAttribute("2")]   public class C2Table   {       public string Id { getset; }   }

 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

相关文章

  • SqlSugar常见问题汇总
    1、已有打开的与此Command相关联的DataReader,必须首先将它关闭。ThereisalreadyanopenDataReaderassociatedwiththisConnectionwhichmustbeclosedfirst.或者出现connectionisclosed出现这个错一般是线程安全引起的解决方案: https://www.donet5.com/Home/......
  • SqlSugar的Repository
    1、仓储说明仓储可以让你的方法更加的规范,需要什么方法都封装到仓储中,下次就能重复使用,并且能很好的和你业务拆分开 这种设计模式简单粗暴用起来也方便,文章下面有可以运行的DEMO 2、仓储方法仓储有一套自带的数据库操作方法,比起db.xx.xxx来说可能更简便些满足一些常用需......
  • SqlSugar的查询函数SqlFunc
    用法我们可以使用SqlFunc这个类调用Sql函数,用法如下:db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.Name) == SqlFunc.ToLower("JACK")).ToList(); C#函数支持一些常用的C#函数.ToString .Contains .Length.ToLower .ToUpper .ToSubstrin......
  • SqlSugar的Where用法
    1、普通表达式查询//id=@idvar list=db.Queryable<Student>().Where(it => it.Id == id).ToList(); //多个条件var list2=db.Queryable<Student>().WhereIF(id>0,it => it.Id == id)// 如果id>0 添加条件 id=@id  .WhereIF(name!=null,it => it.nam......
  • SqlSugar的Select用法
    Select位置正常情况:应该在最后面,一般是.Where(..).OrderBy(..).Select(..).ToList()特殊情况:如果Select不是最后一个位置,则Select要加MergeTable()合并成一个表,Select(...).MergeTable().Where语法糖:Select(...).MergeTable()在新版本中可以用SelectMergeTable(it=>newx......
  • SqlSugar跨库查询/多库查询
    一、跨库方式1:跨库导航(5.1.3.24)优点1:支持跨服务器,支持跨数据库品种,支持任何类型数据库 优点2:  超级强大的性能,能达到本库联表性能缺点:不支持子表过滤主表(方案有ToList后在内存过滤,如果分页可以查前1000条主表在内存分页前端只显示前10页)[Tenant("db2")] //......
  • SqlSugar新增数据
    1、插入方式1.1单条插入实体//返回插入行数db.Insertable(insertObj).ExecuteCommand(); //都是参数化实现//异步: await db.Insertable(insertObj).ExecuteCommandAsync() //插入返回自增列 (实体除ORACLE外实体要配置自增,Oracle需要配置序列)db.Insertable(in......
  • SqlSugar更新数据
    1、根据实体对象更新所谓按实体对象更新就是:db.Updateable(参数对象)有参数的重载db.Updateable(实体或者集合).ExecuteCommand() //右标题1 下面的所有菜单优点1、代码少2、支持各种批量修改缺点1、不支持表达式和sql函数2、依赖 实体对象,没实体对象就需......
  • SqlSugar删除数据
    1、根据实体删除1.1强类型实体 需要配置主键,根据主键删除需要给实体配置主键,参考文档实体配置//单个实体db.Deleteable<Student>(new Student() { Id = 1 }).ExecuteCommand(); //List<实体> (可以不加Where)List<Student> list=new List<Student>(){......
  • SqlSugar基础查询
    查所有List<Student> list=db.Queryable<Student>().ToList()//select * from Student查询总数int count=db.Queryable<Student>().Count()//select count(1) from Student按条件查询db.Queryable<Student>().Where(it=>it.Id......