如何枚举LINQ查询?

roy*_*yco 4 linq vb.net

这一开始似乎是一个愚蠢的问题,但请继续阅读.

我知道LINQ查询是延迟的,只有在枚举查询时才会执行,但我无法确定何时发生这种情况.当然在For Each循环中,将枚举查询.遵循的经验法则是什么?如果这是一个巨大的结果,我不想两次意外地枚举我的查询.

例如,System.Linq.Enumerable.First是否枚举整个查询?我要求性能原因.我想将LINQ结果集传递给ASP.NET MVC视图,我也想分别传递First元素.两次列举结果将是痛苦的.

每次枚举LINQ查询时,打开某种警告我会很棒.这样,当我偶然两次枚举时,我可以捕捉到场景.

Jon*_*eet 8

您可以非常轻松地添加自己的日志记录,以查看正在发生的情况.除此之外,懒惰/急切位相当清楚.基本上它可以是懒惰的 - 任何时候返回类型是IEnumerable<T>IOrderedEnumerable<T>.这些人可能很懒,因为你不能在没有打电话的情况下获得任何数据GetEnumerator().比较一下First()- 例如 - 它必须为您返回一个值.它不能推迟任何事情.

一般来说,如果要确保不会多次评估查询,请调用ToListToArray打开它,然后多次使用该结果.同样,这些方法必须立即返回列表或数组,这两者都不允许延迟填充.评估查询,但随后它与生成的填充集合有效地断开连接 - 查询将不会再次执行,无论您检查列表多少.

除了懒惰/急切的问题,还有流媒体/非流媒体:该方法会从源可读的所有内容中读取所有内容,还是只是"啜饮"它,在需要时读取.同样,一般情况下LINQ只会在必要时读取 - 所以虽然Reverse是非流式(但仍然是懒惰的),Where并且Select正在流式传输.


Jar*_*Par 5

关于何时枚举LINQ查询以及何时不进行查询,没有严格的规则.部分原因是某些方法将会或不会基于查询源的基础类型.

这是一个快速分解.这绝不是一个彻底的分解,主要是我在5分钟内想出来的.

聚合函数

他们完全立即列举了清单.它们通常由返回标量值的扩展方法发现.例如Sum,Min,Max,Count,Last等...

注意:Count和Last不一定要枚举整个列表.如果底层类型是可转换的,则ICollection<T>它们将使用更有效的方法.

列表选择器的前面

他们只查看列表的第一个元素,可能是第二个元素.它们是First,FirstOrDefault,Single,SingleOrDefault.

以上是引用不带谓词的版本.如果他们采用谓词,他们更好地归类为查询(见下文)

查询

它们只会枚举执行操作所需的最小数量的列表.这可以是1个元素,也可以是整个列表的数量.

示例:Any,Contains

创建一个新列表,不要立即执行枚举.

这是LINQ中的绝大多数运营商.枚举新列表时会产生成本.示例:选择,Where,Group,Join,SkipWhile,Skip.