web-dev-qa-db-fra.com

Méthodes d'extension LINQ - Any () vs. Where () vs. Exists ()

Malheureusement, les noms de ces méthodes forment des termes de recherche terribles et je n’ai pas trouvé de bonne ressource pour expliquer la différence entre ces méthodes - par exemple, quand les utiliser.

Merci.

Modifier:

Le type de requête que j'essaie de comprendre parfaitement ressemble à ceci:

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

Et merci à tous ceux qui ont répondu.

53
asfsadf

Where renvoie une nouvelle séquence d'éléments correspondant au prédicat.

Any renvoie une valeur booléenne; il existe une version avec un prédicat (auquel cas elle renvoie si les éléments correspondent ou non) et une version sans (dans ce cas, elle indique si la requête contient jusqu'à présent des éléments).

Je ne suis pas sûr de Exists - ce n'est pas un opérateur de requête standard LINQ. S'il existe une version pour Entity Framework, peut-être qu'il en vérifie l'existence à l'aide d'une clé - une sorte de forme spécialisée de Any? (Il existe une méthode Exists dans List<T> qui est similaire à Any(predicate) mais antérieure à LINQ.)

89
Jon Skeet

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

a.Books est la liste des livres de cet auteur. La propriété est automatiquement créée par Linq-to-Sql, à condition que vous ayez défini une relation de clé étrangère.

Donc, a.Books.Any(b => b.BookID == bookID) est traduit par "l'un des livres de cet auteur possède-t-il un ID de bookID", ce qui donne l'expression complète "Qui sont les auteurs du livre avec l'identifiant id bookID?"

Cela pourrait aussi être écrit quelque chose comme

  from a in context.Authors
  join b in context.Books on a.AuthorId equal b.AuthorID
  where b.BookID == bookID
  select a;

METTRE À JOUR: Any() pour autant que je sache, ne retourne qu'une bool. Sa mise en œuvre effective est:

 public Any(this IEnumerable<T> coll, Func<T, bool> predicate)
 {
     foreach(T t in coll)
     {
         if (predicte(t))
            return true;
     }
     return false;
 }
8
James Curran

Pour que vous puissiez le trouver la prochaine fois, voici comment vous recherchez les extensions énumérables Linq. Les méthodes sont des méthodes statiques d'Enumerable, donc Enumerable.Any, Enumerable.Where et Enumerable.Exists.

Comme le troisième ne donne aucun résultat utilisable, j'ai trouvé que vous vouliez dire List.Exists, donc:

Je recommande également hookedonlinq.com , car il contient des guides très complets et clairs, ainsi que des explications claires sur le comportement des méthodes Linq en ce qui concerne le défi et la paresse.

7
Dykam

Any - Fonction booléenne renvoyant la valeur true lorsqu'un objet de la liste satisfait à la condition définie dans les paramètres de la fonction. Par exemple:

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

Where - fonction qui renvoie la liste avec tous les objets de la liste satisfaisant les conditions définies dans les paramètres de la fonction. Par exemple:

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

Existe - fondamentalement identique à aucun mais ce n'est pas générique - il est défini dans la classe List, tandis que Any est défini sur l'interface IEnumerable.

3
Ivan Ferić

IEnumerable introduit un certain nombre d'extensions qui vous aident à transmettre votre propre délégué et à appeler le résultat à partir de IEnumerable. La plupart d'entre eux sont par nature de type Func

Le Func prend un argument T et retourne TResult. 

En cas de 

Where - Func: Il faut donc IEnumerable of T et renvoie un bool. Le where retournera finalement le IEnumerable de T pour lequel Func renvoie true. 

Donc si vous avez 1,5,3,6,7 comme IEnumerable et que vous écrivez .where (r => r <5), il retournera un nouvel IEnumerable de 1,3. 

Any - Func est fondamentalement similaire dans la signature, mais renvoie true uniquement lorsqu'un des critères renvoie true pour IEnumerable. Dans notre cas, il retournera vrai car il y a peu d'éléments présents avec r <5. 

Exists - D'un autre côté, le prédicat ne renverra vrai que lorsqu'un des prédicats retournera vrai. Donc, dans notre cas, si vous passez .Exists (r => 5) retournera true car 5 est un élément présent dans IEnumerable. 

1
abhishek
foreach (var item in model.Where(x => !model2.Any(y => y.ID == x.ID)).ToList())
{
enter code here
}

même travail que vous pouvez également faire avec Contains

deuxièmement, Where est une nouvelle liste de valeurs ..__; troisièmement, utiliser Exist n’est pas une bonne pratique, vous pouvez atteindre votre cible à partir de Any et contains

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

J'espère que cela effacera votre confusion.

0
Jawwad Ali Khan

Any () renvoie true si l'un des éléments d'une collection répond aux critères de votre prédicat.

Where () renvoie un énumérable de tous les éléments d'une collection qui répondent aux critères de votre prédicat.

Exists () fait la même chose que tout sauf qu'il s'agit simplement d'une implémentation plus ancienne qui existait déjà dans IList avant Linq.

0
Jimmy Hoffa