簡體   English   中英

c#了解LINQ查詢中的AsEnumerable

[英]c# Understanding AsEnumerable in LINQ query

代碼如下:

var mids = _db.Members
     .GroupBy(m => new { m.MemberID, m.CreatedDate })
     .Where(m => m.All(s => s.Status == 1) && m.Key.CreatedDate.Date == DateTime.Today)
     .Select(m=>m);

我收到運行時錯誤:LINQ to Entities不支持指定的類型成員'Date'。 僅支持初始值設定項,實體成員和實體導航屬性

當我將_db.Members.AsEnumerable()添加到它工作的第一行時。

我的理解是.AsEnumerable()強制查詢在客戶端執行。 所以在上面的代碼中,AsEnumerable運算符將查詢轉換為2部分,在服務器端選擇並在客戶端休息(group by,where)。

有人可以驗證我的理解是否正確? 以及沒有.AsEnumerable()的代碼失敗的原因?

你的理解是正確的。 在調用AsEnumerable之后,無法再查詢數據源,它又回到簡單的“給我一切”模式,這意味着所有數據都被傳輸到客戶端,任何進一步的操作都在本地完成。

這也是為什么查詢不能正常工作的原因:為了使它工作,你在LINQ方法中使用的所有表達式都必須可以翻譯成數據源所理解的任何語言 - 因為它是查詢提供者有責任進行翻譯,你也會受到編程支持的任何限制。

在這種特定情況下(假設為EF),可以通過手動將屬性訪問替換為規范函數TruncateTime來修復查詢以在可查詢模式下工作:

.Where(m => m.All(s => s.Status == 1) 
    && EntityFunctions.TruncateTime(m.Key.CreatedDate) ==
       EntityFunctions.TruncateTime(CurrentDateTime()))

當你想切換到LINQ to Objects時 ,經常使用AsEnumerable ,主要是因為你想使用Linq to Entities不支持的一些功能。 當您使用AsEnumerable() ,您正在轉換為IEnumerable<T> ,它基本上將處理從數據源(具有所有數據和索引等)移動到您的應用程序。 換句話說,如果您不使用AsEnumerable()LINQ to Entities將把您的查詢轉換為SQL,它將在您的數據源中遠程執行。 如果您想查看有關此主題的更多信息,我建議您閱讀這篇文章

正如Jon所說, Entity Framework提供了一組函數來處理可以直接轉換為SQL的日期,這些EntityFunctions位於EntityFunctions命名空間中。 這些映射到所謂的“規范函數”,這意味着SQL有1:1的轉換

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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