Какой у вас опыт написания LINQ-запросов в C#?

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

Ответ

Да, обширный опыт работы с LINQ (Language Integrated Query) в различных контекстах.

Основные области применения:

  • LINQ to Objects: Для работы с коллекциями в памяти (List<T>, массивы).
  • LINQ to Entities (EF Core): Для построения и выполнения запросов к базе данных.
  • LINQ to XML: Для обработки XML-документов.

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

  1. Синтаксис запросов (Query Syntax) и методов расширения (Method Syntax):

    // Query Syntax (похож на SQL)
    var result = from user in users
                 where user.Age > 18
                 orderby user.Name
                 select user;
    
    // Method Syntax (чаще используется)
    var result = users.Where(u => u.Age > 18).OrderBy(u => u.Name).ToList();
  2. Отложенное (Deferred) и немедленное (Immediate) выполнение:

    • IQueryable<T> и IEnumerable<T> (до вызова ToList(), First(), Count()) строят запрос, но не выполняют его. Это позволяет EF Core оптимизировать итоговый SQL.
    • Методы агрегации (ToList(), ToArray(), First()) форсируют немедленное выполнение.
  3. Типичные операции:

    // Проекция (Select)
    var names = users.Select(u => u.FullName);
    
    // Группировка (GroupBy)
    var usersByCity = users.GroupBy(u => u.City)
                           .Select(g => new { City = g.Key, Count = g.Count() });
    
    // Соединение (Join)
    var userOrders = from user in dbContext.Users
                     join order in dbContext.Orders on user.Id equals order.UserId
                     select new { user.UserName, order.TotalAmount };
    
    // Агрегация
    var total = orders.Sum(o => o.Amount);
    var averageAge = users.Average(u => u.Age);

Важно: При работе с EF Core нужно понимать, какие операции могут быть переведены в SQL, а какие выполнятся в памяти клиента (например, вызов не маппированных методов .ToString("N")), чтобы избежать проблем с производительностью.