LINQ 扩展方法 - Any() vs. Where() vs. Exists()
Posted
技术标签:
【中文标题】LINQ 扩展方法 - Any() vs. Where() vs. Exists()【英文标题】:LINQ extension methods - Any() vs. Where() vs. Exists() 【发布时间】:2010-09-13 18:24:10 【问题描述】:不幸的是,这些方法的名称构成了糟糕的搜索词,我一直无法找到一个很好的资源来解释这些方法之间的区别——比如何时使用它们。
谢谢。
编辑:
我试图完全理解的查询是这样的:
context.Authors.Where(a => a.Books.Any(b => b.BookID == bookID)).ToList();
感谢所有回答的人。
【问题讨论】:
我也会推荐101 LINQ Samples。 类似问题:***.com/questions/879391/… 【参考方案1】:Where
返回与谓词匹配的新项目序列。
Any
返回一个布尔值;有一个带有谓词的版本(在这种情况下,它返回是否有任何项目匹配)和一个没有谓词的版本(在这种情况下,它返回查询到目前为止是否包含任何项目)。
我不确定Exists
- 它不是 LINQ 标准查询运算符。如果有实体框架的版本,也许它会根据一个键检查是否存在——Any
的一种特殊形式? (List<T>
中有一个 Exists
方法,它类似于 Any(predicate)
,但早于 LINQ。)
【讨论】:
@JonH:是的,正如我所发布的,它是List<T>
的一部分 - 不是 LINQ 的一部分。
但是在功能上,.Any
和.Exists
完全一样。
@Flater:Exists
的哪个版本? List<T>.Exists
?【参考方案2】:
context.Authors.Where(a => a.Books.Any(b => b.BookID == bookID)).ToList();
a.Books
是该作者的书籍列表。如果您设置了外键关系,则该属性由 Linq-to-Sql 自动创建。
所以,a.Books.Any(b => b.BookID == bookID)
翻译为“此作者的任何书籍的 ID 是否为 bookID”,这使得完整的表达式“谁是 ID 为 bookID 的书籍的作者?”
也可以这样写
from a in context.Authors
join b in context.Books on a.AuthorId equal b.AuthorID
where b.BookID == bookID
select a;
更新:
Any()
据我所知,只返回一个bool
。其有效的实现是:
public Any(this IEnumerable<T> coll, Func<T, bool> predicate)
foreach(T t in coll)
if (predicte(t))
return true;
return false;
【讨论】:
我认为让我感到困惑的部分是 Any() 如何返回布尔值,这意味着我正在阅读“是的,作者的收藏中确实有一本书具有此 BookID。”他们是 Any() 的另一个重载,它返回不同的东西吗? 是的,这就是我感到困惑的原因。 Any() 方法的链接方式对我来说毫无意义。它不返回一本书,而是返回一个布尔值。人活着我在这艘上出海吗。也许我只是需要另一壶咖啡。感谢所有的努力,顺便说一句。 我没有发现问题。 Any() 返回一个布尔值,Where() 需要一个布尔值。大家都很开心! 这顶傻帽让我头疼,有时会让人分心。我相信我最终会得到它。 据我了解 Any() 和 Where() 之间的区别是,如果满足条件,则 Any 返回 true,而 Where 返回满足条件的元素。因此,使用 Any 询问是否有任何书籍具有特定 ID,并使用 Where 询问哪些书籍具有 ID(并让它们返回)【参考方案3】:为了让您下次可以找到它,这里是您搜索可枚举的 Linq 扩展的方法。这些方法是 Enumerable 的静态方法,因此是 Enumerable.Any、Enumerable.Where 和 Enumerable.Exists。
google.com/search?q=Enumerable.Any google.com/search?q=Enumerable.Where由于第三个返回没有可用的结果,我发现你的意思是 List.Exists,因此:
google.com/search?q=List.Exists我也推荐hookedonlinq.com,因为它有非常全面和清晰的指南,以及与延迟和惰性相关的 Linq 方法行为的清晰解释。
【讨论】:
感谢您的链接。我搜索了 "ienumerable.any()" ,我猜这很接近,但没用。【参考方案4】:Any - 当列表中的任何对象满足函数参数中设置的条件时返回 true 的布尔函数。例如:
List<string> strings = LoadList();
boolean hasNonEmptyObject = strings.Any(s=>string.IsNullOrEmpty(s));
Where - 返回列表的函数,列表中包含满足函数参数中设置的条件的所有对象。例如:
IEnumerable<string> nonEmptyStrings = strings.Where(s=> !string.IsNullOrEmpty(s));
存在 - 与 any 基本相同,但不是通用的 - 它定义在 List 类中,而 Any 定义在 IEnumerable 接口上。
【讨论】:
您的第二个示例无法编译,因为 Where 返回IEnumerable<T>
。【参考方案5】:
IEnumerable 引入了相当多的扩展,可帮助您传递自己的委托并从 IEnumerable 调用返回的结果。它们中的大多数本质上是 Func 类型
Func 接受一个参数 T 并返回 TResult。
万一
Where - Func : 所以它需要 T 的 IEnumerable 并返回一个布尔值。 where 最终将返回 Func 返回 true 的 T 的 IEnumerable。
因此,如果您将 1,5,3,6,7 作为 IEnumerable 并编写 .where(r => r
Any - Func 在签名上基本相似,但仅当任何条件为 IEnumerable 返回 true 时才返回 true。在我们的例子中,它将返回 true,因为 r
Exists - 另一方面,只有当任何一个谓词返回 true 时,谓词才会返回 true。 所以在我们的例子中,如果你通过 .Exists(r => 5) 将返回 true,因为 5 是 IEnumerable 中存在的元素。
【讨论】:
【参考方案6】:Any()
如果集合中的任何元素满足您的谓词条件,则返回 true。 (Any()
不会遍历整个集合,因为它会在第一次匹配时返回。)
Where()
返回集合中满足谓词条件的所有元素的可枚举。
【讨论】:
不在 IList 上 - 仅在List<T>
【参考方案7】:
foreach (var item in model.Where(x => !model2.Any(y => y.ID == x.ID)).ToList())
enter code here
Contains
也可以完成同样的工作
其次,Where
为您提供新的值列表。
第三,使用Exist
不是一个好习惯,你可以通过Any
和contains
来达到你的目标
EmployeeDetail _E = Db.EmployeeDetails.where(x=>x.Id==1).FirstOrDefault();
希望这能消除您的困惑。
【讨论】:
以上是关于LINQ 扩展方法 - Any() vs. Where() vs. Exists()的主要内容,如果未能解决你的问题,请参考以下文章