Практическое руководство. Создание запросов LINQ на языке C#

В этом разделе рассматриваются три способа создания запросов LINQ на языке C#.

  1. Использование синтаксиса запроса.

  2. Использование синтаксиса метода.

  3. Использование сочетания синтаксиса запроса и синтаксиса метода.

В следующем примере демонстрируются простые запросы LINQ при использовании каждого из перечисленных выше синтаксисов.Общее правило таково: следует использовать (1) всегда, когда это возможно; (2) и (3) при необходимости.

ПримечаниеПримечание

Эти запросы работают с простыми коллекциями в памяти, однако базовый синтаксис идентичен синтаксису, использованному в LINQ to SQL и LINQ to XML.

Пример

Синтаксис запроса

Лучше всего для создания запросов использовать синтаксис запроса, создавая выражения запросов.В следующем примере показано три выражения запроса.В первом выражении демонстрируется фильтрация или ограничение результатов путем применения условий в предложении where.Оно возвращает все элементы в исходной последовательности со значениями больше 7 и меньше 3.Второе выражение демонстрирует сортировку возвращаемых результатов.Третий запрос демонстрирует группировку результатов.Он возвращает две группы на основе первой буквы слова.

// Query #1.
List<int> numbers = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// The query variable can also be implicitly typed by using var
IEnumerable<int> filteringQuery =
    from num in numbers
    where num < 3 || num > 7
    select num;

// Query #2.
IEnumerable<int> orderingQuery =
    from num in numbers
    where num < 3 || num > 7
    orderby num ascending
    select num;

// Query #3.
string[] groupingQuery = { "carrots", "cabbage", "broccoli", "beans", "barley" };
IEnumerable<IGrouping<char, string>> queryFoodGroups =
    from item in groupingQuery
    group item by item[0];

Обратите внимание, что тип запросов — IEnumerable<T>.Все эти запросы можно написать с помощью var, как показано в примере ниже.

var query = from num in numbers...

В каждом из приведенных выше примеров фактическое выполнение запроса откладывается до использования переменной запроса в операторе foreach.Дополнительные сведения см. в разделе Введение в запросы LINQ (C#).

Синтаксис метода

Некоторые операции запросов должны быть выражены в виде вызова метода.Чаще всего используются методы, возвращающие одноэлементные числовые значения, например Sum, Max, Min, Average и т.д.Эти методы всегда должны быть вызваны последними в запросе, поскольку они представляют только одно значение и не могут служить источником дополнительных действий запроса.В следующем примере демонстрируется вызов метода в выражении запроса.

List<int> numbers1 = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
List<int> numbers2 = new List<int>() { 15, 14, 11, 13, 19, 18, 16, 17, 12, 10 };
// Query #4.
double average = numbers1.Average();

// Query #5.
IEnumerable<int> concatenationQuery = numbers1.Concat(numbers2);

Если у метода есть параметры, они представлены в виде лямбда-выражения, как показано в следующем примере.

// Query #6.
IEnumerable<int> largeNumbersQuery = numbers2.Where(c => c > 15);

В предыдущих запросах только запрос №4 выполнялся немедленно.Причина заключается в том, что он возвращает одиночное значение, а не универсальную коллекцию IEnumerable<T>.Сам метод должен использовать foreach для вычисления значения.

Любой их перечисленных ранее запросов можно написать с использованием неявной типизации с помощью var, как показано в следующем примере.

// var is used for convenience in these queries
var average = numbers1.Average();
var concatenationQuery = numbers1.Concat(numbers2);
var largeNumbersQuery = numbers2.Where(c => c > 15);

Смешанный синтаксис запроса и метода

В этом примере демонстрируется использование синтаксиса метода для результатов предложения запроса.Нужно всего лишь заключить выражение запроса в скобки, а затем применить оператор точки и вызвать метод.В следующем примере запрос #7 возвращает количество чисел, значение которых лежит в диапазоне от 3 до 7.Однако в общем случае лучше использовать вторую переменную для хранения результатов вызова метода.Таким образом, будет меньше вероятность перепутать запрос с результатами запроса.

// Query #7.

// Using a query expression with method syntax
int numCount1 =
    (from num in numbers1
     where num < 3 || num > 7
     select num).Count();

// Better: Create a new variable to store
// the method call result
IEnumerable<int> numbersQuery =
    from num in numbers1
    where num < 3 || num > 7
    select num;

int numCount2 = numbersQuery.Count();

Запрос №7 возвращает одиночное значение, а не коллекцию, поэтому он выполняется мгновенно.

Предыдущий запрос можно написать с использованием неявной типизации с помощью var, как показано в следующем примере:

var numCount = (from num in numbers...

Можно использовать синтаксис метода следующим образом.

var numCount = numbers.Where(n => n < 3 || n > 7).Count();

Можно использовать явную типизацию следующим образом.

int numCount = numbers.Where(n => n < 3 || n > 7).Count();

См. также

Задачи

Пошаговое руководство. Написание запросов на C# (LINQ)

Ссылки

Предложение where (Справочник по C#)

Основные понятия

Выражения запросов LINQ (Руководство по программированию на C#)

Другие ресурсы

LINQ