В языке C# предопределено порядочное число операций запросов. Некоторые часто применяемые из них перечислены в табл. 13.2. В дополнение к неполному списку операций, приведенному в табл. 13.3, класс
System.Linq.Enumerable
предлагает набор методов, которые не имеют прямого сокращенного обозначения в виде операций запросов С#, а доступны как расширяющие методы. Эти обобщенные методы можно вызывать для трансформации результирующего набора разными способами (
Reverse<>
,
ToArray<>
,
ToList<>
и т.д.). Некоторые из них применяются для извлечения одиночных элементов из результирующего
набора, другие выполняют разнообразные операции над множествами (
Distinct<>
,
Union<>
,
Intersect<>
и т.п.), а есть еще те, что агрегируют результаты (
Count<>
,
Sum<>
,
Min<>
,
Мах<>
и т.д.).
Чтобы приступить к исследованию более замысловатых запросов LINQ, создайте новый проект консольного приложения по имени
FunWithLinqExpressions
и затем определите массив или коллекцию некоторых выборочных данных. В проекте
FunWithLinqExpressions
вы будете создавать массив объектов типа
ProductInfo
, определенного следующим образом:
namespace FunWithLinqExpressions
{
class ProductInfo
{
public string Name {get; set;} = "";
public string Description {get; set;} = "";
public int NumberInStock {get; set;} = 0;
public override string ToString
=> $"Name={Name}, Description={Description},
Number in Stock={NumberInStock}";
}
}
Теперь заполните массив объектами
ProductInfo
в вызывающем коде:
Console.WriteLine("***** Fun with Query Expressions *****\n");
// Этот массив будет основой для тестирования...
ProductInfo[] itemsInStock = new[] {
new ProductInfo{ Name = "Mac's Coffee",
Description = "Coffee with TEETH", NumberInStock = 24},
Description = "Bland as Possible", NumberInStock = 120},
new ProductInfo{ Name = "Crunchy Pops",
Description = "Cheezy, peppery goodness",
NumberInStock = 2},
new ProductInfo{ Name = "RipOff Water",
Description = "From the tap to your wallet",
NumberInStock = 100},
new ProductInfo{ Name = "Classic Valpo Pizza",
Description = "Everyone loves
pizza!", NumberInStock = 73}
};
// Здесь мы будем вызывать разнообразные методы!
Console.ReadLine;
Базовый
синтаксис выборки
Поскольку синтаксическая корректность выражения запроса LINQ проверяется на этапе компиляции, вы должны помнить, что порядок следования операций критически важен. В простейшем виде каждый запрос LINQ строится с использованием операций
from
,
in
и
select
. Вот базовый шаблон, который нужно соблюдать:
var результат =
from сопоставляемыйЭлемент in контейнер
select сопоставляемыйЭлемент;
Элемент после операции
from
представляет элемент, соответствующий критерию запроса LINQ; именовать его можно по своему усмотрению. Элемент после операции in представляет контейнер данных, в котором производится поиск (массив, коллекция, документ XML и т.д.).
Рассмотрим простой запрос, не делающий ничего кроме извлечения каждого элемента контейнера (по поведению похожий на SQL-оператор
По правде говоря, это выражение запроса не особенно полезно, т.к. оно выдает подмножество, идентичное содержимому входного параметра. При желании можно извлечь только значения
Name
каждого товара, применив следующий синтаксис выборки:
Чтобы получить определенное подмножество из контейнера, можно использовать операцию
where
. Общий шаблон запроса становится таким:
var результат =
from элемент in контейнер
where булевскоеВыражение
select элемент;
Обратите внимание, что операция where ожидает выражение, результатом вычисления которого является булевское значение. Например, чтобы извлечь из аргумента
ProductInfo[]
только товарные позиции, складские запасы которых составляют более 25 единиц, можно написать следующий код: