完整教程: https://www.bilibili.com/video/BV1w14y1N7tS/
1. 右边红色按钮是快捷菜单,可以快速定找到你需要的功能
2. 左边菜单上的搜索功能很强大
3.文档代码中的注释一定要细看,很多细节都在注释中解释
想要学会使用.NET中的ORM 需要知道上下文是什么
1.异步情况: 在同一串await 中是一个上下文 (await 会改变线程和同步是不一样的)
2.同步情况: 在同一个线程是同一个上下文
你可以使用 SqlSugarClient (非单例)或者 SqlSugarScope (单例) 对数据库进行增、删、查、改等功能
SqlSugarClient | 优点:性能比SqlSugarScope有5%左右提升 缺点: db不能跨上下文使用,需要new出一个新对象(和Dapper一样), 偶发错误难排查适合有经验用户 模式:不能单例 |
SqlSugarScope (5.0.3.4) 特色功能 | 如果没有.NET 开发经验的推荐使用 SqlSugarScope 可以解决线程安全问题,无脑使用,目前只有2种情况需要注意一下 1、异步漏掉await ,没有await需要db替换成db.CopyNew() ,不想加CopyNew就需要排查是否有漏掉 2、Task.WhenAll必须要用Task.Run(async=>await 异步方法 ) 需要用Task.Run包一下(CopyNew也行) 支持同一个上下文共享事务 模式: 单例模式 SqlSugarScope一直new会内存泄露 一定要用单例 |
注意非单例模式用的是SqlSugarClient , 禁止用SqlSugarScope
SqlSugarClient 每次请求new一个新对象,db禁止跨上下文使用,IOC建议用Scope或者瞬发注入
//查询所有 public static void Demo() { //创建数据库对象 SqlSugarClient Db= new SqlSugarClient(new ConnectionConfig(){ ConnectionString = "连接符字串", DbType = DbType.SqlServer, IsAutoCloseConnection = true}, db=>{ //5.1.3.24统一了语法和SqlSugarScope一样,老版本AOP可以写外面 db.Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine(sql);//输出sql,查看执行sql 性能无影响 //5.0.8.2 获取无参数化SQL 对性能有影响,特别大的SQL参数多的,调试使用 //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars) } //注意多租户 有几个设置几个 //db.GetConnection(i).Aop }); //建表 //db.CodeFirst.InitTables<Student>(); 更多看文档迁移 //查询表的所有 var list = db.Queryable<Student>().ToList(); //插入 db.Insertable(new Student() { SchoolId = 1, Name = "jack" }).ExecuteCommand(); //更新 db.Updateable(new Student() { Id = 1, SchoolId = 2, Name = "jack2" }).ExecuteCommand(); //删除 db.Deleteable<Student>().Where(it => it.Id == 1).ExecuteCommand(); } //实体与数据库结构一样 public class Student { //数据是自增需要加上IsIdentity //数据库是主键需要加上IsPrimaryKey //注意:要完全和数据库一致2个属性 [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } public int? SchoolId { get; set; } public string Name { get; set; } }
SqlSugarClient 出现偶发错误全部换成SqlSugarScope进行测试,如果换了不报错了那么证明就是
线程安全问题,你也可以直接使用SqlSugarScope因为他是线程安全的 ,用SqlSugarScope要改成单例不然会有内存增加风险
Scope我们需要用SqlSugarClient
//错误 不是委托 services.AddScope<ISqlSugarClient>(new SqlSugarClient(){...}); //错误 SqlSugarClient不能单例 services.AddSingleton<ISqlSugarClient>(it=>new SqlSugarClient(...){}); //正确 是委托并且是Scoped services.AddScope<ISqlSugarClient>(it=>new SqlSugarClient(...){});
SqlSugarScope 请使用单例模式,配置参数有2种周期
(A):全局生效
(B): 当前上下文生效
public class SqlSugarHelper //不能是泛型类 { //多库情况下使用说明: //如果是固定多库可以传 new SqlSugarScope(List<ConnectionConfig>,db=>{}) 文档:多租户 //如果是不固定多库 可以看文档Saas分库 //用单例模式 public static SqlSugarScope Db= new SqlSugarScope(new ConnectionConfig() { ConnectionString = "Server=.xxxxx",//连接符字串 DbType = DbType.SqlServer,//数据库类型 IsAutoCloseConnection = true //不设成true要手动close }, db=> { //(A)全局生效配置点,一般AOP和程序启动的配置扔这里面 ,所有上下文生效 //调试SQL事件,可以删掉 db.Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine(sql);//输出sql,查看执行sql 性能无影响 //5.0.8.2 获取无参数化 SQL 对性能有影响,特别大的SQL参数多的,调试使用 //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars) } //多个配置就写下面 //db.Ado.IsDisableMasterSlaveSeparation=true; //注意多租户 有几个设置几个 //db.GetConnection(i).Aop }); } //(B)当前上下文生效配置点,一般多租户相关操作写在这儿 //db.GetConnectionxxx 只在当前上下文有效,不会共享 //如果是程序启动时的配置全部到A里面去 //建表 //db.CodeFirst.InitTables<Student>(); 更多看文档迁移 //查询表的所有 var list=SqlSugarHelper.Db.Queryable<Student>().ToList(); //插入 SqlSugarHelper.Db.Insertable(new Student(){ SchoolId = 1, Name = "jack" }).ExecuteCommand(); //更新 SqlSugarHelper.Db.Updateable(new Student(){ Id = 1,SchoolId=2,Name="jack2" }).ExecuteCommand(); //删除 SqlSugarHelper.Db.Deleteable<Student>().Where(it => it.Id == 1).ExecuteCommand(); //实体与数据库结构一样 public class Student { //数据是自增需要加上IsIdentity //数据库是主键需要加上IsPrimaryKey //注意:要完全和数据库一致2个属性 [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } public int? SchoolId { get; set; } public string Name { get; set; } }
错误写法1
//错误 => 本质是 get set会一直创建新对象 public static SqlSugarScope Db=> new ...(); //错误 不能get set public static SqlSugarScope Db{get{ retun new xxx}} //错误 不能是方法,调一次方法会创建一次 public static SqlSugarScope Db(){ return new xxx} //错误 SqlSugarClient不能单例只能用 SqlSugarScope public static SqlSugarClient Db=new ...(); //正确写法 public static SqlSugarScope = new ...();
错误写法2:不能在泛型类中new
public class DbContext<T> //错误原因:DbContext<T>.Db 随着T不同他的实例也会不同 { public static SqlSugarScope Db=new ...(); //应该提取到非泛型类或者IOC单例注入 } //正确用法 public class DbContext<T> { public static SqlSugarScope Db = SqlSugarHelper.Db; //在建一个类 }
错误写法3:不能在构造函数内部new
public class DbContext { public DbContext() { Db=new SqlSugarScope..(); //new一次DbContext会创建一个实例 } public static SqlSugarScope Db ; } //正确用法 public static SqlSugarScope Db= new xxxx();
步骤1:
SqlSugarScope线程安全对象可能避免大多数的线程安问问题
1、SqlSugarClient换成SqlSugarScope (SqlSugarScope 要用单例不然内存会增加)
2、多租户: db.GetConnection 换成 db.GetConnectionScope
步骤2:
如果按步骤1改了还报错那么肯定就下面2种情况:
1、异步方法不写await 需要db替换成db.CopyNew() ,不想加CopyNew就需要排查是否有漏掉await
2、Task.WhellAll必须要用Task.Run(async=>await 异步方法 ) 必须用Task.Run包一下(db.CopyNew也可以)
https://www.donet5.com/Home/Doc?typeId=2352
AddSingleton 我们需要用SqlSugarScope单例对象
//错误 不能是委托 services.AddSingleton<ISqlSugarClient>(it=>new SqlSugarScope(...){});//不能有it=> //错误 不是单例 services.AddScoped<ISqlSugarClient>(..) //错误 不能是委托 var sugar=new SqlSugarScope(...){}; services.AddSingleton<ISqlSugarClient>(it=>sugar);//不能有it=> //正确 (SqlSugarScope只能单例注入并且禁止委托参数) var sugar=new SqlSugarScope(...){}; services.AddSingleton<ISqlSugarClient>(sugar);
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 } }); var childA=db.GetConnection("A"); var childB=db.GetConnection("B");
详细教程:https://www.donet5.com/Home/Doc?typeId=2246
SqlSugarClient是通过ConnectionConfig进行传参数详细参数如下
名称 | 描述 | 必填 |
---|---|---|
DbType | 数据库类型 | 是 |
ConnectionString | 连接字符串 | 是 |
IsAutoCloseConnection | 自动释放和关闭数据库连接,如果有事务事务结束时关闭,否则每次操作后关闭 | |
ConfigureExternalServices | 一些扩展层务的集成 | |
MoreSettings | 更多设置 | |
SlaveConnectionConfigs | 主从设置 | |
LanguageType | 提示错误可以设置语言 |
设置超时时间
//Sql超时 db.Ado.CommandTimeOut = 30;//单位秒 //db.Open 连接超时 //在连接池符串加上 Connection Timeout=10 ,默认是30秒,单位秒
版本要求:5.0.6.5 preview05 +
db.Ado.IsValidConnection() //如果时间长,可以在连接字符串配置 连接超时时间 //上面写法如果写到事务中会影响事务 //事务中我会可以new一个新对象处理 db.CopyNew().Ado.IsValidConnection()
SqlSugarClient Db= new SqlSugarClient(new ConnectionConfig(){ ConnectionString = "连接符字串", DbType = DbType.SqlServer, IsAutoCloseConnection = true}, db=>{ //5.1.3.24统一了语法和SqlSugarScope一样,老版本AOP可以写外面 db.Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine(sql);//输出sql,查看执行sql 性能无影响 //5.0.8.2 获取无参数化SQL 对性能有影响,特别大的SQL参数多的,调试使用 //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars) } //注意多租户 有几个设置几个 //db.GetConnection(i).Aop }); //老版本 //版本太老没有db=>{}委托写在下面一行就行了
打印和上面有区别,需要一个一个设置
//注意: //如果你用的 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); }; });
错误提示可以设置相应的语言
1.枚举说明
public enum LanguageType { Default=0, //中&英 Chinese=1, //处理过的异常尽量中文,未处理的还是英文 English=2 //全部英文 }
2.用例
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, LanguageType=LanguageType.English,//只显示英文 IsAutoCloseConnection = true });
1.事务中是长连接
2.手动释放模式是长连接(不推荐需要手动释放)
3.自动释放中 不使用事务我们可以用OpenAlways实现长连接
//5.0.6.3 using (db.Ado.OpenAlways()) { db.Queryable... db.Insertable... //比如当前会话生效的临时表就需要长连接,不然创建了访问不了 }
新功能:5.0.8.1
推荐用默认的,这样多种数据库使用不报错,当然你也可以强制设置
db.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings { DbMinDate = DateTime.MinValue//默认最小时间是 1900-01-01 00:00:00.000 };
2016 © donet5.comApache Licence 2.0