为什么ToLookup和GroupBy不同?

时间:2012-04-18 18:14:47

标签: c# linq

.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?为什么要存在?

3 个答案:

答案 0 :(得分:155)

  

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

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

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

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

构建查询对象;故事的结尾。

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

逻辑上它们是相同的,但每个的性能影响完全不同。调用ToLookup意味着我想要一个由组组织的整个事物的缓存。调用GroupBy意味着“我正在构建一个对象来表示'如果我按组组织它们会是什么样的?'”

答案 1 :(得分:81)

用简单的LINQ世界词语:

  • ToLookup() - 立即执行
  • GroupBy() - 延期执行

答案 2 :(得分:14)

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

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