这一开始似乎是一个愚蠢的问题,但请继续阅读.
我知道LINQ查询是延迟的,只有在枚举查询时才会执行,但我无法确定何时发生这种情况.当然在For Each循环中,将枚举查询.遵循的经验法则是什么?如果这是一个巨大的结果,我不想两次意外地枚举我的查询.
例如,System.Linq.Enumerable.First是否枚举整个查询?我要求性能原因.我想将LINQ结果集传递给ASP.NET MVC视图,我也想分别传递First元素.两次列举结果将是痛苦的.
每次枚举LINQ查询时,打开某种警告我会很棒.这样,当我偶然两次枚举时,我可以捕捉到场景.
您可以非常轻松地添加自己的日志记录,以查看正在发生的情况.除此之外,懒惰/急切位相当清楚.基本上它可以是懒惰的 - 任何时候返回类型是IEnumerable<T>或IOrderedEnumerable<T>.这些人可能很懒,因为你不能在没有打电话的情况下获得任何数据GetEnumerator().比较一下First()- 例如 - 它必须为您返回一个值.它不能推迟任何事情.
一般来说,如果要确保不会多次评估查询,请调用ToList或ToArray打开它,然后多次使用该结果.同样,这些方法必须立即返回列表或数组,这两者都不允许延迟填充.评估查询,但随后它与生成的填充集合有效地断开连接 - 查询将不会再次执行,无论您检查列表多少.
除了懒惰/急切的问题,还有流媒体/非流媒体:该方法会从源可读的所有内容中读取所有内容,还是只是"啜饮"它,在需要时读取.同样,一般情况下LINQ只会在必要时读取 - 所以虽然Reverse是非流式(但仍然是懒惰的),Where并且Select正在流式传输.
关于何时枚举LINQ查询以及何时不进行查询,没有严格的规则.部分原因是某些方法将会或不会基于查询源的基础类型.
这是一个快速分解.这绝不是一个彻底的分解,主要是我在5分钟内想出来的.
他们完全立即列举了清单.它们通常由返回标量值的扩展方法发现.例如Sum,Min,Max,Count,Last等...
注意:Count和Last不一定要枚举整个列表.如果底层类型是可转换的,则ICollection<T>它们将使用更有效的方法.
他们只查看列表的第一个元素,可能是第二个元素.它们是First,FirstOrDefault,Single,SingleOrDefault.
以上是引用不带谓词的版本.如果他们采用谓词,他们更好地归类为查询(见下文)
它们只会枚举执行操作所需的最小数量的列表.这可以是1个元素,也可以是整个列表的数量.
示例:Any,Contains
这是LINQ中的绝大多数运营商.枚举新列表时会产生成本.示例:选择,Where,Group,Join,SkipWhile,Skip.
| 归档时间: |
|
| 查看次数: |
764 次 |
| 最近记录: |