为什么ToLookup和GroupBy不同?

Shl*_*omo 100 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?为什么要存在?

Eri*_*ert 161

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

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

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

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

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

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

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

  • @casperOne:我认为你没理解我的观点.即使在LINQ-to-objects的情况下,调用GroupBy*仍然*不会迭代集合.(正如Aducci在你删除的答案中指出的那样.)这是一个根本的区别. (20认同)
  • @EricLippert:但这只是实现的副作用还是*保证*当你调用ToLookup时,无论对实现做了什么改变,都会迭代枚举? (11认同)
  • 渴望解释它.我认为'ToMetaType'的语言意味着渴望; 虽然显然需要实施.另一个'To'都渴望(ToList,ToArray,ToDictionary).多谢你们. (10认同)
  • @Will:你提出了一个很好的观点; 文档并不能保证ToLookup是"渴望"的.它可能应该注意到. (9认同)
  • 海报没有专门针对`IQueryable <T>`表示.你的答案涵盖了这种情况,但当它只是简单的"IEnumerable <T>"(LINQ-to-Objects)时,似乎没有理由使用一个而不是另一个,这就是我相信@Shlomo是试着去.*不是*IQueryable <T>`情况,而是LINQ-to-Objects情况. (6认同)

sll*_*sll 87

在简单的LINQ世界中:

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


All*_*nek 15

两者相似,但用于不同的场景..ToLookup()返回已经包含所有组(但不是组的内容)的即用型对象.另一方面,.GroupBy()返回一个延迟加载的组序列.

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