Почему ToLookup и GroupBy отличаются?


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

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

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

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

3 83

3 ответа:

зачем мне вообще возиться с GroupBy? Почему он должен существовать?

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

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

что происходит, когда вы вызываете GroupBy на такой объект?

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

когда этот объект запроса перечисляется затем выполняется анализ таблицы на сервере базы данных и сгруппированные результаты отправляются обратно по требованию несколько за раз.

логически они то же самое, но производительность из каждого совершенно разные. Вызов ToLookup означает Я хочу кэш всего этого прямо сейчас, организованный группой. Вызов GroupBy означает "Я создаю объект для представления вопроса "Что бы это было все выглядит так, будто я организовал их по группам?'"

в простых словах LINQ-world:

  • ToLookup() - немедленное исполнение
  • GroupBy() - отложенное выполнение

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

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