我有两个linq表达式给出相同的结果。任何人都可以解释它们之间的快速和原因吗?
if (lstEmployees.Where(cond => cond.EmployeeID == empID).Select(col => col.IsManager).FirstOrDefault())
{
...
}
或
if (lstEmployees.Any(cond => cond.EmployeeID == empID && cond.IsManager))
{
...
}
答案 0 :(得分:0)
lstEmployees.Any(cond => cond.EmployeeID == empID && cond.IsManager)
它应该很快。只检查数据是否可用并返回true或false。 第二种方法应该返回对象。
答案 1 :(得分:0)
Any()将停止迭代符合条件的第一个项目,只返回一个bool(true = found或false not found)。 Where()将继续贯穿整个序列,以便它可以返回条件匹配的项目的完整结果。总结 - 如果你只需要知道一个条件是否真实至少一次并且不关心满足你条件的实际项目,Any()就是你更快的解决方案。
这是Any()的实现。一旦谓词返回true,就看它是如何从foreach循环中退出的。
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source) {
if (predicate(element)) return true;
}
return false;
}
编辑:根据评论 - 对于过滤序列的Where()表达式,它实际上需要进行评估。选择的评估将确定您是否实际完成了整个序列。因此,如果你做一个foreach打印出所有结果,你将完成整个序列。在Where()上使用FirstOrDefault(),您也可以获得提前终止的好处。立即评估Any()。
答案 2 :(得分:0)
理论上
lstEmployees.Any(cond => cond.EmployeeID == empID && cond.IsManager)
应该更快或更平等。因为它将通过一个迭代循环完成所有必要的操作。 但实际上它很大程度上取决于LINQ提供商。提供商有可能优化
lstEmployees.Where(cond => cond.EmployeeID == empID).Select(col => col.IsManager).FirstOrDefault()
更简单的查询,你根本不会感到任何不同。
但我认为最好使用.Any在这里,只是因为它更短,业务逻辑更清晰易懂。
答案 3 :(得分:0)
Any
会更正确。因为Any会在符合条件的集合中的第一个实体上返回true,但是FirstOrDefault
将在您的情况下执行相同的操作(从性能的角度来看)。 FirstOrDefault
可能更慢的唯一情况是当您使用第三方数据连接器,bad
实现转换linq表达式到SQL查询。
因此,通常只需使用Any
即可确保使用最快的解决方案。