簡體   English   中英

C# 擴展方法類型

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

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