Что такое LINQ в C#?

«Что такое LINQ в C#?» — вопрос из категории C# Core, который задают на 51% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

LINQ (Language Integrated Query) — это набор технологий в C#, интегрирующих возможности запросов непосредственно в язык. Он предоставляет единый, декларативный синтаксис для работы с данными из различных источников: коллекций в памяти (массивы, списки), баз данных, XML, JSON и других.

Ключевые концепции:

  1. Единый синтаксис: Одинаковые операторы (Where, Select, OrderBy) работают с разными источниками данных.
  2. Два стиля написания:
    • Методный синтаксис (Method Syntax): Цепочка методов расширения.
      var result = collection.Where(x => x.Age > 18)
                         .OrderBy(x => x.Name)
                         .Select(x => x.Email);
    • Синтаксис запросов (Query Syntax): Напоминает SQL.
      var result = from item in collection
               where item.Age > 18
               orderby item.Name
               select item.Email;

Два основных режима выполнения:

Аспект LINQ to Objects LINQ to Entities (или др. провайдеры)
Источник данных Любая коллекция, реализующая IEnumerable<T>. Источник, реализующий IQueryable<T> (напр., DbSet в Entity Framework).
Место выполнения Локально, в памяти приложения. Удаленно (например, на сервере БД). Запрос транслируется в язык источника (SQL).
Механизм Лямбда-выражения компилируются в делегаты. Лямбда-выражения преобразуются в деревья выражений (Expression Trees) для анализа и трансляции.
Отложенное выполнение Да. Запрос выполняется только при итерации или вызове материализующих методов (ToList(), ToArray(), Count()). Да. Запрос строится и отправляется на сервер только при материализации.

Практический пример с Entity Framework:

// Эта часть выполняется как IQueryable - запрос уходит в БД
var adultsQuery = dbContext.Users
    .Where(u => u.Age >= 18) // Превращается в SQL WHERE clause
    .OrderBy(u => u.LastName); // Превращается в SQL ORDER BY

// Запрос выполняется в БД только здесь, возвращаются данные в память
List<User> adultList = adultsQuery.ToList();

// Дальнейшая работа - это LINQ to Objects в памяти
var firstNames = adultList.Select(u => u.FirstName).Distinct();

Основные операторы:

  • Фильтрация: Where
  • Проекция: Select, SelectMany
  • Сортировка: OrderBy, OrderByDescending, ThenBy
  • Группировка: GroupBy
  • Агрегация: Count, Sum, Average, Min, Max
  • Соединение: Join, GroupJoin
  • Кванторы: Any, All, Contains

Преимущества: повышение читаемости кода, безопасность типов на этапе компиляции, производительность (особенно с IQueryable), унификация подхода к данным.