.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? Почему он должен существовать?
GroupBy
ЕстьIQuerable
,ILookup
нетLookup
, ноGroupBy
создают его, когда результат перечисляется ссылкамиource.microsoft.comОтветы:
Что происходит, когда вы вызываете ToLookup для объекта, представляющего таблицу удаленной базы данных с миллиардом строк в ней?
Миллиард строк отправляется по сети, и вы создаете таблицу поиска локально.
Что происходит, когда вы вызываете GroupBy для такого объекта?
Создается объект запроса; конец истории.
Когда этот объект запроса перечисляется, анализ таблицы выполняется на сервере базы данных, и сгруппированные результаты отправляются обратно по запросу по несколько раз.
Логически это одно и то же, но влияние каждого на производительность совершенно разное. Вызов ToLookup означает, что я хочу, чтобы прямо сейчас кэш был организован по группам . Вызов GroupBy означает: «Я создаю объект для представления вопроса:« Как бы эти вещи выглядели, если бы я организовал их по группам? »»
источник
IQueryable<T>
представление. Ваш ответ охватывает эту ситуацию, но когда это просто olIEnumerable<T>
(LINQ-to-Objects), может показаться, что нет причин использовать одно вместо другого, что, как я считаю, пытается достичь @Shlomo. Не тотIQueryable<T>
случай, а случай LINQ-to-Objects.Простыми словами LINQ-world:
ToLookup()
- немедленное исполнениеGroupBy()
- отсроченное исполнениеисточник
Они похожи, но используются в разных сценариях.
.ToLookup()
возвращает готовый к использованию объект, в котором уже загружены все группы (но не содержимое группы). С другой стороны,.GroupBy()
возвращает ленивую последовательность групп.У разных поставщиков LINQ может быть разное поведение для быстрой и отложенной загрузки групп. С LINQ-to-Object это, вероятно, не имеет большого значения, но с LINQ-to-SQL (или LINQ-to-EF и т. Д.) Операция группировки выполняется на сервере базы данных, а не на клиенте, поэтому вы можете захотеть чтобы выполнить дополнительную фильтрацию по ключу группы (который генерирует
HAVING
предложение), а затем получить только некоторые из групп вместо всех..ToLookup()
не допускает такой семантики, поскольку все элементы сгруппированы с готовностью.источник