为什么ToLookup和Groupby不同

本文关键字:不同 Groupby ToLookup 为什么 | 更新日期: 2023-09-27 18:31:36

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

为什么ToLookup和Groupby不同

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

在表示包含 10 亿行的远程数据库表的对象上调用 ToLookup 时会发生什么情况?

十亿行通过网络发送,您可以在本地生成查找表。

在此类对象上调用 GroupBy 时会发生什么情况?

生成一个查询对象;故事结束。

枚举该查询对象后,将在数据库服务器上完成表的分析,并根据需要一次发送几个分组结果。

从逻辑上讲,它们是一回事,但每个的性能影响完全不同。调用ToLookup意味着我现在想要按组组织的整个事情的缓存。 调用 GroupBy 的意思是"我正在构建一个对象来表示以下问题:'如果我按组组织这些东西会是什么样子?'"

用简单的 LINQ 世界的话来说:

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

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

不同的 LINQ 提供程序对于组的急切和延迟加载可能具有不同的行为。使用 LINQ-to-Object 可能没有什么区别,但使用 LINQ-to-SQL(或 LINQ-to-EF 等)时,分组操作是在数据库服务器而不是客户端上执行的,因此您可能希望对组键(生成 HAVING 子句)执行额外的筛选,然后只获取部分组而不是所有组。 .ToLookup()不允许这样的语义,因为所有项目都急切地分组。