[英]Timeout expired when using a Func<> instead of a lambda
鑒於:
public EntityAddress ReadSingle(Func<EntityAddress, bool> predicate)
{
//var result = Context.CV3Address.FirstOrDefault(a => a.GUID == 1100222);
var result = Context.CV3Address.FirstOrDefault(predicate);
return result;
}
FirstOrDefault(a => a.GUID == 1100222);
立即返回結果。
FirstOrDefault(predicate);
導致超時異常。 注意謂詞= lambda表達式
我的懷疑是,后一種方法試圖拉低所有記錄,而這種記錄不會在如此大的表中發生。
為什么會這樣?
發生這種情況的原因是謂詞的類型,而應改為
Expression<Func<CV3Address, bool>>
如果謂詞是一個表達式樹(如上所述),並且Context.CV3Address
是IQueryable<CV3Address>
則EF可以將表達式樹轉換為SQL,並直接從數據庫中獲取結果。
另一方面,如果謂詞是Func<CV3Address, bool>
(委托;指向已編譯代碼的指針),則無法將其轉換為SQL。 因此,LINQ沒有其他選擇可將您的存儲庫視為IEnumerable<CV3Address>
,這是可以在內存中過濾的序列。 這具有需要從數據庫中提取所有記錄以對其進行過濾的副作用。
如果對謂詞進行硬編碼,則編譯器可以將其視為表達式樹或委托,並且由於Context.CV3Address
的類型,因此會將其視為表達式樹。
FirstOrDefault(a => a.GUID == 1100222)
創建一個表達式樹,該樹使用LINQ to Entities在數據庫服務器上運行查詢。
FirstOrDefault(predicate)
下載整個表並在本地運行過濾器。
您需要更改方法以采用表達式樹:
Expression<Func<CV3Address, bool>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.