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 google.com/search?q=Enumerable.Exists

由于第三个返回没有可用的结果,我发现你的意思是 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&lt;T&gt;【参考方案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&lt;T&gt;【参考方案7】:
foreach (var item in model.Where(x => !model2.Any(y => y.ID == x.ID)).ToList())

enter code here

Contains 也可以完成同样的工作

其次,Where 为您提供新的值列表。 第三,使用Exist不是一个好习惯,你可以通过Anycontains来达到你的目标

EmployeeDetail _E = Db.EmployeeDetails.where(x=>x.Id==1).FirstOrDefault();

希望这能消除您的困惑。

【讨论】:

以上是关于LINQ 扩展方法 - Any() vs. Where() vs. Exists()的主要内容,如果未能解决你的问题,请参考以下文章

C# Linq ANY vs ALL - 性能 [关闭]

Linq

C#-Linq源码解析之Any

Linq扩展方法

为啥 C# 编译器在使用 LINQ 方法 Any() 时会创建私有 DisplayClass,我该如何避免它?

ToList()、Any()、Count()、Sum() 上的 Linq 错误