簡體   English   中英

使用Func <>而不是lambda時,超時已過期

[英]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.CV3AddressIQueryable<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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM