Dapper升級SqlSugar問題彙總

最近羣裏有個小夥伴把Dapper遷移SqlSugar幾個不能解決的問題進行一個彙總,我正好寫一篇文章來講解一下

 

一、sql where in傳參問題:

  SELECT * FROM users where id IN @ids 

答: SqlSugar中應該是

var sql="SELECT * FROM users where id IN (@ids)";//要有()和dapper有差異
var list=db.Ado.SqlQuery<Users>(sql,new {ids=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; }
}

效果圖

image.png

 

 六、 獲取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;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章