简单示例,1分钟入门

视频教程

可以用百度网盘在线看: https://pan.baidu.com/s/1B4APxNFSKys70K6cyipsdw

提取码 :9w35


概念 ”上下文“

想要学会使用.NET中的ORM 需要知道上下文是什么

1.异步情况: 在同一串await 中是一个上下文 (await 会改变线程和同步是不一样的)

2.同步情况: 在同一个线程是同一个上下文


创建对象

你可以使用 SqlSugarClient 或者 SqlSugarScope 对数据库进行增、删、查、改等功能

SqlSugarClient

优点:性能比SqlSugarScope有5%左右提升

缺点: db不能跨上下文使用,需要new出一个新对象(和Dapper一样),

偶发错误难排查适合有经验用户

 模式:不能单例

SqlSugarScope (5.0.3.4

特色功能

 如果没有.NET 开发经验的推荐使用 SqlSugarScope

 不用考虑任何线程问题,无脑使用,简单省事,较强性能,

 支持同一个上下文共享事务

 模式: 单例模式   SqlSugarScope一直new会内存泄露 一定要用单例


1、SqlSugarClient  非单例模式

注意非单例模式用的是SqlSugarClient , 禁止用SqlSugarScope

1.1 简单用例

SqlSugarClient 每次请求new一个新对象,db禁止跨上下文使用,IOC建议用Scope或者瞬发注入

    //查询所有
    public static void Demo()
    {
    
     //创建数据库对象
     SqlSugarClient db = new SqlSugarClient(new ConnectionConfig(){
           ConnectionString = "连接符字串", 
           DbType = DbType.SqlServer,
           IsAutoCloseConnection = true});
     
     //调试SQL事件,可以删掉 (要放在执行方法之前)
     db.Aop.OnLogExecuting = (sql, pars) =>
     {
       Console.WriteLine(sql);//输出sql,查看执行sql 性能无影响
       
       //5.0.8.2 获取无参数化SQL 对性能有影响,特别大的SQL参数多的,调试使用
       //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars)
      }
           
     //查询表的所有
     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; }
     }

1.2 偶发错误

 SqlSugarClient 出现偶发错误全部换成SqlSugarScope进行测试,如果换了不报错了那么证明就是

线程安全问题,你也可以直接使用SqlSugarScope因为他是线程安全的 ,用SqlSugarScope要改成单例不然会有内存增加风险

1.3  AddScope IOC

Scope我们需要用SqlSugarClient

//错误  不是委托
services.AddScope<ISqlSugarClient>(new SqlSugarClient(){...});
//错误  SqlSugarClient不能单例
services.AddSingleton<ISqlSugarClient>(it=>new SqlSugarClient(...){});
//正确  是委托并且是Scoped
services.AddScope<ISqlSugarClient>(it=>new SqlSugarClient(...){});



2、SqlSugarScope 单例模式

2.1 简单用例

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;
     });
   }
   //(B)当前上下文生效配置点,一般多租户相关操作写在这儿 
   //db.GetConnectionxxx 只在当前上下文有效,不会共享
   //如果是程序启动时的配置全部到A里面去
  
  //查询表的所有
  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();

2.2 异步方法偶发错误 

 SqlSugarScope 异步不加await会出错,参考文档: 异步

正确方案:

1、从最上层到最下层有没有漏掉await 

2、表达式中调用异步方法一定要注意 表达式不能是Action只能是Task 认真看 异步文档

QuartZ组件:

升级到5.1.3.23-preview03 针对一些特殊情进行了优化处理 

笨方案100%解决问题:

使用强制new db进行验证是否异步错误,CopyNew会强制new出一个SqlSugarClient

await db.CopyNew().Queryable<Order>().ToListAsync();
//如果CopyNew不报错,那么异步肯定是用法有问题,一般出现在Job等复杂的应用中,你也可以直接用CopyNew处理

//如果用到事务提取成变量
var newdb=db.CopyNew();
newdb.BeginTran()...
newdb.Insertable(xx)....
newdb.CommitTran()...

2.3 多租户偶发错误

SqlSugarScope 线程安全, 但是获取出来的子对象确不是线程安全,新版本给出了解决方案

db.GetConnection 换成  db.GetConnectionScope   可以完美解决新功能5.0.7.7-preview03

2.4 原理

https://www.donet5.com/Home/Doc?typeId=2352

2.5  AddSingleton IOC

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  }
});

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()


打印SQL 

sql怎么打印出来

 SqlSugarClient db= new  SqlSugarClient(new ConnectionConfig()
 {
            ConnectionString = "Server=.xxxxx",//连接符字串
            DbType = DbType.SqlServer,
            IsAutoCloseConnection = true //不设成true要手动close
 });
 //要放在执行方法之前
 db.Aop.OnLogExecuting = (sql, pars) =>
 {
  
   Console.WriteLine(sql);//输出sql
   Console.WriteLine(string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value)));//参数
   
   //5.0.8.2 获取无参数化 SQL 
    //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars)
 };

 
 
//下面的操作都会进上面的回调函数 
var list = db.Queryable<Student>().ToList();   
db.Insertable(new Student() { SchoolId = 1, Name = "jack" }).ExecuteCommand();

多租户设置SQL打印和上面有区别,需要一个一个设置

 db.GetConnection("1").OnLogExecuting = (sql, pars) =>
 {
     Console.WriteLine("执行1库"+sql);
 };
 db.GetConnection("0").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 
   });


长连接用法(3种方式)

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 
   };


文档:SqlSugar5.0