В прошлом уроке мы писали LINQ через цепочку методов: .Where(...).OrderBy(...).Select(...). Но в C# есть и второй способ — синтаксис, напоминающий SQL-запросы. Оба делают одно и то же, но выглядят по-разному.
Сравним два способа написать один и тот же запрос — выбрать магов с очками выше 1000 и отсортировать по убыванию:
Синтаксис методов (Method Syntax):
var result = players
.Where(p => p.Score > 1000)
.OrderByDescending(p => p.Score)
.Select(p => p.Name);
Синтаксис запросов (Query Syntax):
var result = from p in players
where p.Score > 1000
orderby p.Score descending
select p.Name;
Результат идентичен. Компилятор превращает синтаксис запросов в вызовы тех же методов — Where, OrderByDescending, Select. Это чистый «синтаксический сахар».
Разберём структуру синтаксиса запросов:
var result = from p in players // Источник данных и переменная диапазона
where p.Score > 1000 // Условие фильтрации
orderby p.Score descending // Сортировка
select p.Name; // Что возвращаем (проекция)
Ключевые слова:
| Ключевое слово | Аналог в синтаксисе методов | Описание |
|---|---|---|
from x in collection |
Исходная коллекция | Объявляет источник и переменную элемента |
where |
.Where() |
Фильтрация |
orderby |
.OrderBy() / .OrderByDescending() |
Сортировка |
select |
.Select() |
Проекция (что вернуть) |
group by |
.GroupBy() |
Группировка |
join |
.Join() |
Соединение коллекций |
На практике оба стиля часто смешиваются. Некоторые операции существуют только в синтаксисе методов — у них нет аналога в синтаксисе запросов:
// Count, First, Take, Skip, Distinct — только методы
int count = (from p in players
where p.Score > 1000
select p).Count();
// Или смешанный подход:
var top3 = (from p in players
orderby p.Score descending
select p.Name).Take(3);
Ещё один пример — один запрос в двух стилях:
// Задача: имена магов с очками больше 1000, в верхнем регистре
// Синтаксис методов
var result1 = players
.Where(p => p.Class == "Маг" && p.Score > 1000)
.Select(p => p.Name.ToUpper());
// Синтаксис запросов
var result2 = from p in players
where p.Class == "Маг" && p.Score > 1000
select p.Name.ToUpper();
// Оба вернут: ["АЛЬБЕРТ", "МЕРЛИН"]
Синтаксис методов — LINQ через цепочку вызовов: .Where().Select().OrderBy(). Используется чаще, все операции доступны.
Синтаксис запросов — SQL-подобная запись: from ... where ... select. Удобен для join и group by. Обязательно заканчивается на select или group.
Компилятор превращает синтаксис запросов в вызовы тех же методов — результат идентичен.
Операции Count, First, Take, Skip, Distinct существуют только в синтаксисе методов.