回覆列表
  • 1 # 月下聽風雨

    C# IQueryable和IEnumerable的區別

    在使用EF查詢資料的時候,我們常用的查詢資料方式有linq to sql,linq to object,

    查詢返回的結果有兩種型別:IQueryable、IEnumerable,兩者內部的處理機制是完全不同的。

    清楚認識,這裡也是一個數據查詢的最佳化點。

    在System.linq名稱空間,有兩個靜態類:Queryable和Enumerable.

    在System.linq.Queryable中,引數接收的是一個表示式型別,返回IQueryable介面

    public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate); public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);

    在System.linq.Enumerable中,引數接收的是一個謂詞表達式,也就是一個委託

    public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate); public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

    那麼在查詢資料使用linq to object的時候,會根據傳遞的引數不同返回不同的型別.

    1.where條件接收表示式,返回IQueryable介面

    2.where條件接收一個謂詞表達式(委託)返回一個IEnumerable介面

    那麼什麼時候用IQueryable<T>,什麼時候用IEnumerable<T>?

    1.Func<>謂詞表達式,就是一個委託,委託一旦呼叫,就立即執行了,將執行結果儲存在記憶體中。

    2.Expression是一個表示式,會儲存拼接表示式樹,直到在執行期最終執行。

    那麼在EF中我們根據條件查詢資料時,不應該把資料一次性載入到本地記憶體中,然後再本地記憶體中進行篩選,如果資料量大了,就崩潰了。

    我們需要將表示式組合好,然後再一起提交到資料庫執行,返回查詢結果。

    (每次在執行where查詢運算子的時候IQueryProvider會為我們建立一個新的IQueryable<T>,呼叫AsEnumerable()方法的時候並不會去實際取值,只是

    得到了一個IEnumerable,所以EF在查詢資料時候不要先取IEnumerable再去篩選資料。執行ToList方法時才會去真正呼叫迭代器GetEnumerator() 取值。真正取值時候,會去執行IQueryProvider中的Excute方法.(解析表示式,然後執行取得結果))

    這就是IQueryable的延遲載入.

    Linq查詢

    LINQ的方法體裡執行了查詢後有三種類型可以返回查詢結果,分別為Count、Single、Tolist。

    1. Count是返回查詢結果的總條數,常用於新增、修改時判斷資料是否重複。

    2. Single只能返回單條資料,當查詢的結果為單條問題時沒什麼問題。可一旦查詢的結果為空或者查詢的結果是兩條以上時,就會報錯,把專案卡的動都不能動。

    3. Tolist是將查詢出來的資料列表化,當有多條資料並且需要找到某條資料時只能透過查詢結果[n].data的方式將資料找出來,Single只需透過查詢結果.data便可找到資料。

  • 2 # 清山月SAX

    這兩者對於查詢內部處理機制是不同的,where的返回型別為IQueryable引數是Expression型別的.LINQ的查詢返回IEnumerable型別

  • 中秋節和大豐收的關聯?
  • 如何使用企業郵箱?做什麼的使用企業郵箱比較好?