Dapper升级SqlSugar问题汇总

  • Dapper升级SqlSugar问题汇总已关闭评论
  • 47 次浏览
  • A+
所属分类:.NET技术
摘要

最近群里有个小伙伴把Dapper迁移SqlSugar几个不能解决的问题进行一个汇总,我正好写一篇文章来讲解一下

最近群里有个小伙伴把Dapper迁移SqlSugar几个不能解决的问题进行一个汇总,我正好写一篇文章来讲解一下

 

一、sql where in传参问题:

  SELECT * FROM users where id IN @ids 

答: SqlSugar中应该是

// SELECT * FROM users where id IN (@ids) var listdb.Ado.SqlQuery<Users>(sql,new {id=new int[]{1,2,3}})   

  

二、Dapper查询出来的Dynamic动态类型,支持获取不存在的属性

   例如:SELECT UserName FROM users

 可以通过 result.UserCode,不会报错 

  答:dynamic expandobject 属性不存在肯定是会报错的 , list[0].id如果不存肯定报错

这个需求还是头一次,因为不报错可能不严谨SQLSugar暂时没有这个方法可以通扩展一个方法实现

using System.Collections.Generic;   using System.Dynamic;      public class ForgivingDynamicObject : DynamicObject   {       private readonly Dictionary<string, object> _members = new Dictionary<string, object>();          public override bool TryGetMember(GetMemberBinder binder, out object result)       {           // 尝试从字典中获取成员,如果不存在则返回null           return _members.TryGetValue(binder.Name, out result) || (result = null) != null;       }          public override bool TrySetMember(SetMemberBinder binder, object value)       {           // 将成员设置到字典中           _members[binder.Name] = value;           return true;       }   } public static class DynamicExtensions { public static ForgivingDynamicObject ToForgivingDynamicObject(this dynamic dynamicObject) { var forgivingObject = new ForgivingDynamicObject(); if (dynamicObject is IDictionary<string, object> dictionary) { foreach (var kvp in dictionary) { forgivingObject.TrySetMember(new SetMemberBinder(kvp.Key, false), kvp.Value); } } return forgivingObject; } }  dynamic expando = new ExpandoObject(); expando.ExistingProperty = "Hello";  // 转换为 ForgivingDynamicObject ForgivingDynamicObject forgivingObj = expando.ToForgivingDynamicObject();  // 访问存在的属性 string value = forgivingObj.ExistingProperty; // "Hello"  // 访问不存在的属性,将返回null而不是抛出异常 string nonExistingValue = forgivingObj.NonExistingProperty; // null 

  

三、表值参数必须传typeName

       Dapper是可以不用传的

       Sqlsugar在5.4.1.152+  下面value可以传null了

 //SqlSugar中用法  var s = new SugarParameter("@p", value);  s.TypeName = "dtTableName";     

 

四、类型转换:在Dapper中很多类型做了兼容处理。

比如:数据库中是string,但值是int  SELECT CAST( id as nvarchar) id  FROM users

Dapper中Query实体时,id允许定义为string,

答:Sqlsugar中类型只支持int转string,不支持string转int

默认不支持反向转换考虑到数据严谨性,防止线上数据因错误数据导致系统出错

解决方案:加上特性让他支持转换

[SugarColumn(SqlParameterDbType=typeof(CommonPropertyConvert))]//ORM自带的也支持重写这个转换类 public DateTime DcValue { get; set; }  

  

五、Dapper 联表VO转换   

l  不支持IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map, object? param = null, IDbTransaction? transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) =>

            MultiMap<TFirst, TSecond, DontMap, DontMap, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType)

主要用于结果集返回之后,包装成一个有层次的对象。

答:

SqlSugar同样可以支持一维对象变成2维对象

var list=db.SqlQueryable<SQLVO>("select 1 as id,'jack' as name ").ToList();                 public class SQLVO  {      [SugarColumn(IsOwnsOne =true)]      public ITEM1 ITEM1 { get; set; }//item1和item2不能有重复字段                    [SugarColumn(IsOwnsOne = true)]      public ITEM2 ITEM2 { get; set; }//item1和item2不能有重复字段   } public class ITEM1  {      public int ID { get; set; } } public class ITEM2 {     public string Name { get; set; } } 

效果图

Dapper升级SqlSugar问题汇总

 

 六、 获取Output

Dapper执行ExecuteReader方法之后,还能通过Get<T>(“params”)获取到。SqlSugar是直接无法获取的,需要包装一次,从DataReaderParameters中获取。 

 答: 暂时没有get方法可以通索引拿出来

 //我们还可以用 GetParameters 来简化参数操作   SugarParameter [] pars =db.Ado.GetParameters(new{p=1,p2=p});   pars[1].Direction=ParameterDirection.Output;   db.Ado.ExecuteCommand(sql,pars);   var outValue=pars[1].Value;