c# - 为什么ToLookup和GroupBy不同?

.GroupBy<TSource, TKey>返回IEnumerable<IGrouping<Tkey, TSource>>. ILookup<TKey, TSource>也实现接口IEnumerable<IGrouping<TKey, TSource>>

.GroupBy<TSource, TKey>返回IEnumerable<IGrouping<Tkey, TSource>>

ILookup具有方便的索引器属性,因此它可以以类字典(或类似查找)的方式使用,而GroupBy可以使用。 GroupBy没有索引器是一种痛苦的工作; 几乎是你可以引用返回对象的唯一方法是循环它(或使用另一个LINQ扩展方法)。 换句话说,任何GroupBy工作的情况下,ToLookup也会起作用。

这一切让我想到为什么我会打扰GroupBy? 为什么要存在?

Shlomo asked 2019-08-13T15:30:07Z
3个解决方案
154 votes

为什么我会打扰GroupBy? 为什么要存在?

当您在表示具有十亿行的远程数据库表的对象上调用ToLookup时会发生什么?

通过线路发送十亿行,并在本地构建查找表。

在这样的对象上调用GroupBy时会发生什么?

构建查询对象; 故事结局。

当枚举该查询对象时,表的分析在数据库服务器上完成,并且分组的结果一次一个地按需发回。

从逻辑上讲,它们是相同的,但每个的性能影响是完全不同的。 调用ToLookup意味着我想要一个由组织组织的整个事物的缓存。 调用GroupBy意味着&#34;我正在构建一个对象来表示问题&#39;如果我按组进行组织,这些事情会是什么样的?&#39;&#34;

Eric Lippert answered 2019-08-13T15:31:12Z
80 votes

在简单的LINQ世界中:

  • GroupBy() - 立即执行
  • GroupBy() - 延期执行
sll answered 2019-08-13T15:31:58Z
13 votes

两者相似,但用于不同的场景。 HAVING返回已准备好使用的对象,该对象已经急切地加载了所有组(但不是组的内容)。 另一方面,.ToLookup()返回延迟加载的组序列。

不同的LINQ提供者可能对组的急切和延迟加载具有不同的行为。 使用LINQ-to-Object它可能没什么区别,但是使用LINQ-to-SQL(或LINQ-to-EF等),分组操作是在数据库服务器而不是客户端上执行的,所以你可能想要 对组密钥(生成一个HAVING子句)进行额外的过滤,然后只获取一些组而不是所有组。 .ToLookup()不允许这样的语义,因为所有项目都是急切分组的。

Allon Guralnek answered 2019-08-13T15:32:36Z
translate from https://stackoverflow.com:/questions/10215428/why-are-tolookup-and-groupby-different