我不知道為什么 LoadData 函式的回傳值(如下所示)在一種情況下支持 FirstOrDefault() 方法而在另一種情況下不支持。在這兩種情況下,它是相同的回傳型別。
唯一的區別是創建動態引數的方式。
public async Task<LookupModel?> UpdateLookup(LookupModel item, Guid newUk)
var p1 = new
{
item.Code,
item.Name,
item.uk,
newUk
};
var result1 = await _db.LoadData<LookupModel, dynamic>("lu.Lookup_Update", p1);
// result1.GetType() = System.Collections.Generic.List`1[DataAccess.Models.Lookups.LookupModel]
var rtv1 = result1.FirstOrDefault(); // ok
var p2 = item.GetUpdateParams(newUk);
var result2 = await _db.LoadData<LookupModel, dynamic>("lu.Lookup_Update", p2);
// result2.GetType() = System.Collections.Generic.List`1[DataAccess.Models.Lookups.LookupModel]
var rtv2 = result2.FirstOrDefault(); // not ok
// This throws an exception as FirstOrDefault() is not defined
return rtv1;
}
// LookupModel
public dynamic GetUpdateParams(Guid newUk)
{
return new
{
this.Code,
this.Name,
this.uk,
newUK
};
}
// LoadData
public async Task<IEnumerable<T>> LoadData<T, U>(string storedProcedure, U parameters, string connectionId = "Default")
{
using IDbConnection connection = new SqlConnection(_config.GetConnectionString(connectionId));
return await connection.QueryAsync<T>(storedProcedure, parameters, commandType: CommandType.StoredProcedure);
}
uj5u.com熱心網友回復:
p2is dynamic,這意味著它result2也是動態的(因為它需要p2作為輸入),并且FirstOrDefault是一種擴展方法。由于result2在編譯時不知道的型別,因此您不能對其呼叫擴展方法。
您仍然可以通過使用實際的靜態方法而不是擴展方法來做到這一點:
var rtv2 = Enumerable.FirstOrDefault(result2);
因為可以在運行時系結靜態方法。
但我只想更改GetUpdateParams它回傳命名型別而不是匿名型別,然后您不必使用dynamic. 這也將為您提供更多的型別安全性,因為編譯器可以進行型別檢查,而您不必等到運行時才能找到型別錯誤。
uj5u.com熱心網友回復:
試試這個
return (await connection
.QueryAsync<T>(storedProcedure, parameters, commandType: CommandType.StoredProcedure))
.ToList();
uj5u.com熱心網友回復:
因為 p1 是具體型別,而 p2 是物件型別(在運行時)。所以在運行時,LoadData 將分別在匿名型別或物件上泛型。由于 object 沒有任何屬性,所以失敗了。
我建議你在呼叫 LoadData 之前將 p2 克隆到一個具體的匿名型別來解決這個問題
Parameters p2clone = new { Code = p2.Code...};
var bar = LoadData(p2clone);
interface Parameters
{
string Code {get;}
string Name {get;}
...
}
您需要這樣做的原因是 Linq 運算式編譯器在傳入的型別上大量使用反射。沒有型別資訊,dapper 無法編譯您的 SQL。
uj5u.com熱心網友回復:
從此行中洗掉等待
//var result1 = await _db.LoadData<LookupModel, dynamic>("lu.Lookup_Update", p1);
var result1 = _db.LoadData<LookupModel, dynamic>("lu.Lookup_Update", p1);
改變
var rtv1 = result1.FirstOrDefault();
到
var rtv1= await result1.FirstOrDefaultAsync()
FirstorDefaultAsync()應該添加所屬的命名空間。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/385964.html
上一篇:常規檔案夾/檔案名C#
