Вопрос по c#, linq – Почему ToLookup и GroupBy разные?

89

.ToLookup<TSource, TKey> возвращаетILookup<TKey, TSource>. ILookup<TKey, TSource> также реализует интерфейсIEnumerable<IGrouping<TKey, TSource>>.

.GroupBy<TSource, TKey> возвращаетIEnumerable<IGrouping<Tkey, TSource>>.

ILookup имеет свойство удобного индексатора, поэтому его можно использовать в словарном (или в виде поиска) способом, тогда как GroupBy не может. GroupBy без индексатора - боль в работе; Практически единственный способ, которым вы можете затем ссылаться на возвращаемый объект, - это проходить по нему (или использовать другой метод расширения LINQ). Другими словами, в любом случае, когда GroupBy работает, ToLookup также будет работать.

Все это оставляет меня с вопросом, зачем мне вообще беспокоиться о GroupBy? Почему это должно существовать?

Я выдвинул эту кандидатуру для повторного открытия, так как вопрос, который предположительно является ее дубликатом, касаетсяIGrouping скорее, чемGroupBy а такжеILookup скорее, чемToLookup, Различия между ними отличаются от различий между ними. Это должно быть видно из различий в ответах между вопросами. Sam
GroupBy ЯвляетсяIQuerable, ILookup не является Magnus
оба они создаютLookup, ноGroupBy создает его при перечислении результатаreferencesource.microsoft.com/#System.Core/System/Linq/… Slai
GroupBy не перечисляет списокToLookup перечисляет это так же, как ToList / ToArray Aducci

Ваш Ответ

3   ответа
80

ToLookup() - immediate execution GroupBy() - deferred execution
13

.ToLookup() возвращает готовый к использованию объект, в который уже загружены все группы (но не содержимое группы). С другой стороны,.GroupBy() возвращает лениво загруженную последовательность групп.

Разные провайдеры LINQ могут по-разному реагировать на нетерпеливую и ленивую загрузку групп. С LINQ-to-Object это, вероятно, не имеет большого значения, но с LINQ-to-SQL (или LINQ-to-EF и т. Д.) Операция группировки выполняется на сервере базы данных, а не на клиенте, и поэтому вы можете захотеть сделать дополнительную фильтрацию на ключе группы (который генерируетHAVING пункт), а затем получить только некоторые из групп вместо всех..ToLookup() не допускает такой семантики, так как все элементы сгруппированы.

153

Что происходит, когда вы вызываете ToLookup для объекта, представляющего таблицу удаленной базы данных с миллиардом строк в ней?

Миллиард строк передается по сети, и вы создаете таблицу поиска локально.

Что происходит, когда вы вызываете GroupBy для такого объекта?

Объект запроса построен; конец истории.

Когда этот объект запроса перечислен, тогда анализ таблицы сделанon the database server и сгруппированные результаты отправляются обратноon demand несколько за один раз.

Логически они одно и то же, ноperformance implications каждого совершенно разные. Вызов ToLookup означаетI want a cache of the entire thing right now organized by group, Вызов GroupBy означает «Я создаю объект для представления вопроса», как бы эти вещи выглядели, если бы я организовал их по группам? »

@EricLippert: Но это только побочный эффект от реализации илиguaranteed что перечислимое будет повторяться при вызове ToLookup, независимо от того, какие изменения внесены в реализацию?
Стремление объясняет это. Язык «ToMetaType»; Я думаю, подразумевает рвение; хотя это, очевидно, оставлено на усмотрение реализации. Другие "To" все стремятся (ToList, ToArray, ToDictionary). Спасибо, парни. Shlomo
Постер не предназначен специально дляIQueryable<T> представление. Ваш ответ охватывает эту ситуацию, но когда это простоIEnumerable<T> (LINQ-to-Objects) может показаться, что нет причины использовать один поверх другого, к чему, как я полагаю, @Shlomo пытается добраться.Not IQueryable<T> случай, но случай LINQ-to-Objects.
@casperOne: я думаю, вы не поняли мою точку зрения. Даже в случае LINQ-to-objects вызов GroupBystill не перебирает коллекцию (Как указал Aducci в ответе, который вы удалили.) Это принципиальная разница.
@Will: Вы делаете отличную точку зрения; документация не гарантирует, что ToLookup является "нетерпеливым". Это, вероятно, следует отметить, что.

Похожие вопросы