[英]C# extension methods types
在 C# 中,有兩套擴展方法(例如 Where)工作在 IEnumerable 和 IQueryable 之上。 其中哪些用於操作內存對象,哪些用於處理數據庫。? 請幫忙
IEnumerable<T>.Where
方法 extension.which 接受Func<TSource, bool> predicate
參數,強制過濾發生在內存中。 在從數據庫查詢數據時, IEnumerable
在服務器端執行select query
,在客戶端加載內存中的數據,然后過濾數據。 對於IEnumerable<T>
情況,它將是LINQ-to-object
,這意味着所有與原始查詢匹配的對象都必須從數據庫加載到內存中。 IEnumerable
適用於從內存集合(如 List、Array 等)中查詢數據。
IQueryable<T>.Where
方法擴展,它接受Expression<Func<TSource, bool>> predicate
參數。 請注意,這是一個表達式,而不是一個委托,它允許將 where 條件轉換為數據庫條件。
從數據庫查詢數據時, IQueryable
在服務器端使用所有過濾器執行select query
。 不同之處在於IQueryable<T>
是允許 LINQ-to-SQL(實際上是 LINQ.-to-anything)工作的接口。 因此,如果您進一步優化對IQueryable<T>
查詢,則該查詢將在可能的情況下在數據庫中執行。 IQueryable
適用於從內存外(如遠程數據庫、服務)集合中查詢數據。
IEnumerable<T>
公開枚舉器,它支持對指定類型的集合進行簡單迭代。 所以它用於內存中的對象
IQueryable<T>
提供了評估針對特定數據源的查詢的功能,其中數據類型是已知的。 所以它用於處理數據庫
Reza Jenabi 的回答說的是最重要的部分。
我只想補充一點,有時代碼非常相似,錯誤可能需要一些時間才能注意到。 如果你寫一個方法,如:
public List<Thing> GetList(Func<Thing, bool> filter)
{
return dbContext.Things.Where(filter).ToList();
}
你的“過濾器”不會被翻譯成 SQL。 Things 表的所有內容都將加載到內存中,然后只應用加載數據的過濾器。 在幾乎空的桌子上不明顯,但在有數千條記錄的桌子上成本非常高。
因此,當您希望在 SQL 服務器端執行它時,請注意始終使用Expression<Func>
:
public List<Thing> GetList(Expression<Func<Thing, bool>> filter)
{
return dbContext.Things.Where(filter).ToList();
}
知道這兩種方法將以完全相同的方式調用,例如:
Repository.GetList(t => t.IsMyThing || t.WhateverYouWant);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.