LINQ扩展方法 - Any()vs. Where()vs. Exists()

时间:2010-09-13 18:24:10

标签: c# linq

不幸的是,这些方法的名称造成了可怕的搜索术语,而且我一直无法找到解释这些方法之间差异的好资源 - 就像何时使用每种方法一样。

感谢。

编辑:

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

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

感谢所有回答的人。

7 个答案:

答案 0 :(得分:90)

Where返回与谓词匹配的新项目序列。

Any返回一个布尔值;有一个带有谓词的版本(在这种情况下它会返回是否有任何项匹配)和一个没有的版本(在这种情况下它会返回查询到目前为止是否包含任何项目)。

我不确定Exists - 它不是LINQ标准查询运算符。如果有实体框架的版本,也许它会根据密钥检查是否存在 - 一种特殊形式的Any? (Exists中有一个List<T>方法,类似于Any(predicate),但早于LINQ。)

答案 1 :(得分:8)

  
    

context.Authors.Where(a =&gt; a.Books.Any(b =&gt; b.BookID == bookID))。ToList();

  

a.Books是该作者的书籍清单。如果您设置了外键关系,则该属性由Linq-to-Sql自动创建。

因此,a.Books.Any(b => b.BookID == bookID)转换为“此作者的任何书籍都具有bookID的ID”,这使得完整的表达“谁是具有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;
 }

答案 2 :(得分:7)

这样您下次就可以找到它,这是您搜索可枚举的Linq扩展的方法。这些方法是Enumerable的静态方法,因此Enumerable.Any,Enumerable.Where和Enumerable.Exists。

由于第三个没有返回可用的结果,我发现你的意思是List.Exists,因此:

我还推荐hookedonlinq.com因为这是非常全面和清晰的指南,以及Linq方法在延迟和懒惰方面的行为的清晰解释。

答案 3 :(得分:3)

Any - 布尔函数,当列表中的任何对象满足函数参数中设置的条件时,返回true。例如:

List<string> strings = LoadList();
boolean hasNonEmptyObject = strings.Any(s=>string.IsNullOrEmpty(s));

其中 - 返回列表的函数,列表中的所有对象满足函数参数中设置的条件。例如:

IEnumerable<string> nonEmptyStrings = strings.Where(s=> !string.IsNullOrEmpty(s));

存在 - 基本上与任何一个相同,但它不是通用的 - 它在List类中定义,而Any在IEnumerable接口上定义。

答案 4 :(得分:1)

IEnumerable引入了相当多的扩展,它可以帮助您传递自己的委托并从IEnumerable中调用结果。其中大多数都是Func

类型的性质

Func接受参数T并返回TResult。

如果是

Where - Func:所以它需要Tnumerable of T并返回一个bool。 where将最终返回Func返回true的IE的数量。

因此,如果您有1,5,3,6,7作为IEnumerable并且您编写.where(r =&gt; r&lt; 5)它将返回新的IEnumerable 1,3。

Any - Func在签名中基本相似,但只有当任何条件为IEnumerable返回true时才返回true。在我们的例子中,它将返回true,因为r <5时存在的元素很少。

Exists - 另一方面谓词只有在任何一个谓词返回true时才会返回true。 因此,在我们的情况下,如果你传递.Exists(r =&gt; 5)将返回true,因为5是IEnumerable中存在的元素。

答案 5 :(得分:0)

如果集合中的任何元素符合谓词的条件,Any()将返回true。

Where()返回集合中符合谓词条件的所有元素的可枚举。

Exists()与其他任何东西都做同样的事情,除了它只是在Linq之前IList上的旧实现。

答案 6 :(得分:0)

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();

希望这会清除您的困惑。