Подтвердить что ты не робот

Методы расширения LINQ - Any() vs. Where() vs. Exists()

К сожалению, имена этих методов делают ужасные условия поиска, и я не смог найти хороший ресурс, который объясняет разницу между этими методами - как в том, когда использовать каждый.

Спасибо.

Edit:

Тип запроса, который я пытаюсь полностью понять, выглядит примерно так:

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

И спасибо всем, кто ответил.

4b9b3361

Ответ 1

Where возвращает новую последовательность элементов, соответствующих предикату.

Any возвращает логическое значение; там версия с предикатом (в этом случае она возвращает, соответствуют ли какие-либо элементы) и версия без (в этом случае она возвращает, содержит ли запрос до сих пор какие-либо элементы).

Я не уверен в Exists - это не стандартный оператор запроса LINQ. Если есть версия для Entity Framework, возможно, она проверяет существование на основе ключа - своего рода специализированную форму Any? (Там Exists метод в List<T>, который похож на Any(predicate), но предшествует LINQ.)

Ответ 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) переводится как "У любой из книг этого автора есть идентификатор 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;

UPDATE: Any() насколько мне известно, возвращает bool. Его эффективная реализация:

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

Ответ 3

Просто чтобы найти его в следующий раз, вот как вы ищите перечислимые расширения Linq. Методами являются статические методы Enumerable, поэтому Enumerable.Any, Enumerable.Where и Enumerable.Exists.

Поскольку третий не возвращает никакого полезного результата, я обнаружил, что вы имели в виду List.Exists, таким образом:

Я также рекомендую hookedonlinq.com, поскольку у этого есть очень подробные и понятные руководства, а также четкие объяснения поведения методов Linq в отношение к отсрочке и ленивости.

Ответ 4

Любая логическая функция, возвращающая значение 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.

Ответ 5

IEnumerable вводит довольно много расширений, которые помогают вам передать свой собственный делегат и вызвать результирующий результат из IEnumerable. Большинство из них по характеру типа Func

Func принимает аргумент T и возвращает TResult.

В случае

Где - Func: так требуется IEnumerable из T и возвращает bool. То, где в конечном итоге вернет IEnumerable из T, для которого Func возвращает true.

Итак, если у вас есть 1,5,3,6,7 как IEnumerable, и вы пишете .where(r = > r < 5), он вернет новый IEnumerable из 1,3.

Any - Func в основном похож на подпись, но возвращает true только тогда, когда любой из критериев возвращает true для IEnumerable. В нашем случае он будет возвращать true, поскольку имеется несколько элементов с r < 5.

Exists - Предикат, с другой стороны, вернет true только тогда, когда любой из предикатов возвращает true. Поэтому в нашем случае, если вы пройдете .Exists(r = > 5) вернет true, поскольку 5 - это элемент, присутствующий в IEnumerable.

Ответ 6

Any() возвращает true, если какой-либо из элементов в коллекции соответствует вашим критериям предиката.

Где() возвращает перечислимый из всех элементов в коллекции, которые соответствуют вашим критериям предиката.

Exists() делает то же самое, что и все, кроме как только более старая реализация, которая была там на IList еще до Linq.