.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?为什么要存在?
答案 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()
不允许这样的语义,因为所有项目都是热切的分组。