English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Оператор фильтрации Where LINQ

Операторы фильтрации LINQ фильтруют последовательность (набор) по заданным критериям.

В таблице ниже перечислены все доступные операторы фильтрации в LINQ.

Оператор фильтрацииОписание
Where

Возвращает значения из набора по функции предиката.

OfType

Возвращает значения из набора по заданному типу. Однако, это зависит от того, могут ли они быть преобразованы в заданный тип.

Where

Оператор Where (расширяемый метод LINQ) фильтрует набор по заданным условиям и возвращает новый набор. Стандарт можно определить как lambda-выражение или тип Func.

WhereУвеличенные методы имеют два варианта. Оба варианта принимают параметр типа Func. Один вариант требует параметр Func <TSource, bool>, а второй вариант требует параметр Func <TSource, int, bool>, где int используется в качестве индекса:

Перегрузки метода Where:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, 
                                                  Func<TSource, bool> predicate);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, 
                                                  Func<TSource, int, bool> predicate);

Where предложение в синтаксисе запроса

Пример запроса, использующий оператор Where для фильтрации студентов-подростков из заданного набора (серии). Он использует lambda-выражение в качестве функции предиката.

IList<Student> studentList = new List<Student>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
        new Student() { StudentID = 2, StudentName = "Moin", Age = 21 } ,
        new Student() { StudentID = 3, StudentName = "Bill", Age = 18 }
        new Student() { StudentID = 4, StudentName = "Ram", Age = 20 },
        new Student() { StudentID = 5, StudentName = "Ron", Age = 15 } 
    });
var filteredResult = from s in studentList
                    where s.Age > 12 && s.Age < 20
                    select s.StudentName;
Dim studentList = New List(Of Student) From {
        New Student() With {.StudentID = 1, .StudentName = "John", .Age = 13},
        New Student() With {.StudentID = 2, .StudentName = "Moin", .Age = 21},
        New Student() With {.StudentID = 3, .StudentName = "Bill", .Age = 18},
        New Student() With {.StudentID = 4, .StudentName = "Ram", .Age = 20},
        New Student() With {.StudentID = 5, .StudentName = "Ron", .Age = 15}
    }
Dim filteredResult = From s In studentList
                     Where s.Age > 12 And s.Age < 20
                     Select s.StudentName

В приведенном выше примере, filteredResult после выполнения запроса будет включать следующих студентов:

John
Bill
Ron

В теле lambda-выражения в приведенном выше примере запроса: s.Age > 12 && s.Age < 20 в качестве predicate функции для оценки каждого ученика в наборе.Func<TSource, bool>

Кроме того, вы можете использовать тип Func в сочетании с анонимными методами, передавая их в качестве таких predicate функции (результаты идентичны):

Func<Student,bool> isTeenAger = delegate(Student s) {}} 
                                    return s.Age > 12 && s.Age < 20; 
                                });
var filteredResult = from s in studentList
                     where isTeenAger(s)
                     select s;

Вы также можете вызывать любые методы, соответствующие параметру Func, через перегруженный метод Where().

public static void Main()
{
    var filteredResult = from s in studentList
                         where isTeenAger(s)
                         select s;
}
public static bool IsTeenAger(Student stud)
{
    return stud.Age > 12 && stud.Age < 20;  
}

Метод расширения where

В отличие от запросного синтаксиса, вам нужно передавать весь lambda-выражение в качестве функции предиката, а не только тело выражения в синтаксисе LINQ.

var filteredResult = studentList.Where(s => s.Age > 12 && s.Age < 20);
Dim filteredResult = studentList.Where(Function(s) s.Age > 12 And s.Age < 20)

Как было сказано выше,WhereУ расширения методов также есть вторая загрузка, которая включает индекс текущего элемента в集合е. Если необходимо, этот индекс можно использовать в логике.

В следующем примере используется подзапрос where для фильтрации нечетных элементов из集合а, возвращая только четные элементы. Помните, что индекс начинается с нуля.

IList<Student> studentList = new List<Student>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
        new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
        new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
        new Student() { StudentID = 4, StudentName = "Ram", Age = 20 } ,
        new Student() { StudentID = 5, StudentName = "Ron", Age = 19 } 
    });
var filteredResult = studentList.Where((s, i) => { 
            if (i % 2 == 0) // Если это четное
                return true;
                
        return false;
    });
foreach (var std in filteredResult)
        Console.WriteLine(std.StudentName);

 

Вывод:
John
Bill
Ron

Многочисленные where-подзапросы

Вы можете несколько раз вызывать расширяемый метод Where() в одном LINQ запросе.

Пример: Многочисленные where-подзапросы в синтаксисе запросов C#
var filteredResult = from s in studentList
                        where s.Age > 12                    
                        where s.Age < 20                    
                        select s;
Пример: Многочисленные where-подзапросы в методическом синтаксисе C#
var filteredResult = studentList.Where(s => s.Age > 12).Where(s => s.Age < 20);

  Следует запомнить

  1. Where Используется для фильтрации集合 по заданным критериям.

  2. 其中 расширяемый метод имеет два overload. Использование второго overload позволяет определить индекс текущего элемента в集合е.

  3. Синтаксис методов требует полного lambda-выражения из расширяемого метода Where, а синтаксис запросов требует только тела выражения.

  4. В одном LINQ запросе несколькоWhereРасширяемые методы эффективны.