3

如果我知道集合中只有一个匹配项,有没有办法告诉 Linq 这一点,以便它在找到它时中止搜索?

我假设这两个都在返回一个项目之前搜索完整的集合?

var fred = _people.Where((p) => p.Name == "Fred").First();
var bill = _people.Where((p) => p.Name == "Bill").Take(1);

编辑:人们似乎对FirstOrDefault, 或SingleOrDefault. 这些与我的问题无关。如果集合为空,它们只是提供一个默认值。正如我所说,我知道我的收藏有一个匹配的项目。

AakashM 的评论是我最感兴趣的。我会出现我的假​​设是错误的,但我很感兴趣为什么。例如,当 linq to objects 在我的示例代码中运行 Where() 函数时,它如何知道对其返回值还有进一步的操作?

4

3 回答 3

7

你的假设是错误的。LINQ 大量使用延迟执行和惰性求值。这意味着,例如,当您调用 时Where(),它实际上并没有迭代集合。只有当你迭代它返回的对象时,它才会迭代原始集合。它会以一种懒惰的方式来做:只做必要的事情。

因此,在您的情况下,两个查询都不会迭代整个集合:两者都只会迭代它直到找到第一个元素,然后停止。

实际上,第二个查询(with Take())甚至不会这样做,它只会在您迭代结果时迭代源集合。

这一切都适用于 LINQ to 对象。其他提供程序(LINQ to SQL 和其他)的行为可能有所不同,但至少延迟执行的原则通常仍然成立。

于 2012-04-20T10:43:54.363 回答
0

我认为First()不会扫描整个集合。它将在第一场比赛后立即返回。但我建议FirstOrDefault()改用。

编辑:

First()和之间的区别FirstOrDefault()(来自 MSDN):

如果 source 不包含任何元素,该First()方法将引发异常。要在源序列为空时返回默认值,请使用该FirstOrDefault()方法。

可枚举的.First

于 2012-04-20T10:15:42.083 回答
-1

替换.Where(.SingleorDefault( 这将为您找到第一个也是唯一的项目。

但是您不能对任何给定的数字执行此操作。如果您需要 2 件物品,则需要获得整个收藏品。

但是,您不必担心时间。最大的努力用于打开数据库连接和建立查询。执行查询不会花费太多时间,因此没有真正的理由中途停止查询 :-)

于 2012-04-20T10:15:10.263 回答