【问题标题】:LINQ extension methods - Any() vs. Where() vs. Exists()LINQ 扩展方法 - Any() vs. Where() vs. Exists()
【发布时间】:2010-09-13 18:24:10
【问题描述】:

不幸的是,这些方法的名称构成了糟糕的搜索词,我一直无法找到一个很好的资源来解释这些方法之间的区别——比如何时使用它们。

谢谢。

编辑:

我试图完全理解的查询是这样的:

context.Authors.Where(a => a.Books.Any(b => b.BookID == bookID)).ToList();

感谢所有回答的人。

【问题讨论】:

标签: c# linq


【解决方案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。

由于第三个返回没有可用的结果,我发现你的意思是 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();
    

    希望这能消除您的困惑。

    【讨论】:

      猜你喜欢
      • 2012-09-07
      • 2010-12-04
      • 2023-03-18
      • 2010-10-27
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 1970-01-01
      相关资源
      最近更新 更多