创建一个相同上下文共享的 数据库操作对象
//单例不要写在泛型类中, 类<T>.Db 这种是无效单例 ,T不同就会有多个实例 public SqlSugarScope Db= new SqlSugarScope (new List<ConnectionConfig>() { new ConnectionConfig(){ConfigId="0",DbType=DbType.SqlServer,ConnectionString="..",IsAutoCloseConnection=true}, new ConnectionConfig(){ConfigId="1",DbType=DbType.MySql, ConnectionString="...",IsAutoCloseConnection=true} //ConfigId用来区别是哪个库 } ,db=> { //如果是GetConnectionScope或者GetConnectionScopeWithAttr这边也应该是GetConnectionScope //如果用的是GetConnection或者GetConnectionWithAttr这边也应该是GetConnection //用哪个就AOP添加哪个 //技巧:这边可以循环处理这个更方便些 db.GetConnection("0").Aop.OnLogExecuting = (sql, p) => { Console.WriteLine(sql); }; db.GetConnection("1").Aop.OnLogExecuting = (sql, p) => { Console.WriteLine(sql); }; //如果是 日志库 不要加AOP防止AOP循环引用 } ); //单例注入(因为是SqlSugarScope应该单例) services.AddSingleton<ISqlSugarClient>(Db); //如果是SqlSugarClient不能单例
如果用IOC看下面注用法
每个GetConnection出来的数据库是独立的数据库操作对象,可以一起使用相互没有任何影响
//方式1:通过Config获取数据库,比较灵活 var db1=db.GetConnection(configId) //非线程安全 var db1=db.GetConnectionScope(configId); //线程安全 (5.0.7.7) //方式2:通过特性获取数据库,一个实体对一个库的时候非常方便 var db2=db.GetConnectionWithAttr<T>() //非线程安全 var db2=db.GetConnectionScopeWithAttr<T>() //线程安全(5.0.7.7) [TenantAttribute("1")]//对应ConfigId=1 public class C1Table { public string Id { get; set; } }
接口说明:
ISqlSugarClien childDb=Db.GetConnection("1");//子Db负责CRUD(没有实现ITenant接口) ITenant tenant=Db;//租户负责多库事务和管理子Db //完整Db的接口关系 SqlSugarScope: ISqlSugarClient, ITenant SqlSugarClient: ISqlSugarClient, ITenant
public class Repository<T> : SimpleClient<T> where T : class, new() { public ITenant itenant = null;//多租户事务、GetConnection、IsAnyConnection等功能 public Repository() { //方式1:.NET CORE自带的IOC 会封装的人用 //需要将注入时用到的Services存到一个静态对象中通过Services获取 base.Context=存储的Services.BuildServiceProvider() .GetService<ISqlSugarClient>() .GetConnectionScopeWithAttr<T>(); //GetConnectionScope(configId)也可以 2.1已介绍了他们区别 itenant=存储的Services.GetService<ISqlSugarClient>().AsTenant();//处理事务 //说明:为什么不用构造函数注入,如果你不用切换仓储方法可以用构造函数注入,如果切换仓储就需要非构造注入 //方式2:SqlSugar.Ioc用法 base.Context =DbScoped.SugarScope.GetConnectionScopeWithAttr<T>();//子Db无租户方法,其他功能都有 //base.Context =DbScoped.SugarScope.GetConnectionScope(configId); 也可以手动获取 itenant = DbScoped.SugarScope;//处理多租户事务、GetConnection、IsAnyConnection等功能 //方式3:Furion框架中用 base.Context= App.GetService<ISqlSugarClient>().AsTenant().GetConnectionScopeWithAttr<T>(); itenant = App.GetService<ISqlSugarClient>().AsTenant(); //方式4:不用Ioc base.Context=单例的SqlSugarScope.GetConnectionScopeWithAttr<T>(); itenant=单例的SqlSugarScope; } }
base.Context=具体数据库对象 可以使用仓储方法在具体数据库进行CRUD
itenant =完整数据库对象 管理多个仓储事务等、还能在使用GetConnection、IsAnyConnection等功能
通过base.仓储方法进行CRUD, itenant负责事务
仓储有哪些方法可以看仓储入门:https://www.donet5.com/Home/Doc?typeId=1228
public class UserRepository { private readonly Repository<Abpusers> rep;//想写几个就写几个 public UserService() { rep= new Repository<Abpusers>(); } //使用事务 public void TestTran() { try { rep.itenant.BeginTran(); rep.Insert(new UserInfo() {... }); var orderDal= rep.ChangeRepository<Repository<Order>>();//切换仓储 orderDal.Insert(new Order() {... }); orderDal.Context.XXXXX rep.itenant.CommitTran(); } catch (Exception ex) { rep.itenant.RollbackTran(); throw ex; } } }
var orderDal=db.GetRepository<Repository<Order>>();) //使用仓储方法 orderDal.Insert(data);
var orderItemDb = rep.ChangeRepository<Repository<OrderItem>>();;
用SqlSugarScope的注意了获取子对象线程安全用法如下
新功能(5.0.7.7preview03+):
this.Context=db.GetConnectionScope(1);//线程安全,子对象也支持了线程安全 this.Context=db.GetConnection(1);//非线安全对象 ,this类需要new ,内部开线程需要new this类
上面主要是原理和实现比较灵活,你也可以用我封好的工作单元 5.0.8.3支持
https://www.donet5.com/Home/Doc?typeId=2360
2016 © donet5.comApache Licence 2.0