簡體   English   中英

AsEnumerable()是否緩存所有結果(LINQ)

[英]Does AsEnumerable() cache all result (LINQ)

當我們在序列上調用查詢運算符時,將調用特定於序列的運算符。
我的意思是,如果我在IEnumerable<>上調用Where<>()運算符,將在Enumerable類中定義將被調用的運算符,如果在IQueryable<>對其進行調用,則將調用Queryable類中定義的那個運算符。

考慮在Enumerable類中定義的Reverse運算符。
如果我想在Iqueryable<>上調用它,則必須使用AsEnumerable<>()運算符首先將其轉換為IEnumerable<>

db.Countries.OrderBy(cntry=>cntry.CountryName).AsEnumerable().Reverse()

但是Reverse運算符必須同時擁有所有記錄,以便可以將它們反轉。
在上面的代碼中,是否所有記錄都首先加載到內存中,然后Reverse()運算符將其反轉?

AsEnumerable除了更改表達式的編譯時類型外,什么也不做。

它是這樣實現的:

public static IEnumerable<T> AsEnumerable<T>(this IEnumerable<T> source)
{
    return source;
}

它甚至不檢查無效性!

唯一的一點是更改編譯時類型,以強制使用Enumerable擴展方法而不是Queryable來執行其余的查詢。 這就像強制轉換-除了強制強制轉換在查詢過程中通常很不方便外,對於匿名類型,無論如何您都無法強制轉換。

因此,它實際上是關於查詢的“源”在枚舉時的作用。 在返回任何結果之前,該源代碼是否將所有內容都加載到內存中? IIRC,LINQ to SQL實際上會將所有內容加載到內存中-但我可能是錯的。 當然, Reverse無論如何都會緩沖任何東西,但這並不意味着它將使用雙倍的內存-在大多數情況下,這僅意味着它將緩沖對對象的引用 它不會為每個對象創建一個新副本。

IQueryable<T>擴展了IEnumerable<T> ,因此AsEnumerable是冗余的。 但是,如果使用它,AsEnumerable將不會貪婪地加載集合(那將是一個非常煩人的“功能”)。 顯然,反向將需要整個過程。 Mono使用List<T>和一個簡單的迭代器生成器實現Enumerable.Reverse ,反向生成。

我相信AsEnumerable的唯一真正目的是強制使用IEnumerable顯式接口實現。

暫無
暫無

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

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