108просмотров
58.1%от подписчиков
23 марта 2026 г.
Score: 119
LINQ теперь умеет LeftJoin и RightJoin без ритуалов #dotnet #efcore #linq В .NET 10 и EF Core 10 появились LeftJoin и RightJoin, так что теперь outer join в LINQ можно писать прямо и читаемо, без привычной конструкции GroupJoin + SelectMany + DefaultIfEmpty. Для .NET-разработчиков это одна из самых приятных мелочей релиза: код стал ближе к SQL по смыслу и заметно проще для чтения. Раньше левое соединение выглядело так:
var query = from customer in context.Customers join order in context.Orders on customer.Id equals order.CustomerId into ordersGroup from order in ordersGroup.DefaultIfEmpty() select new { CustomerName = customer.Name, OrderId = order != null ? order.Id : null, Total = order != null ? order.Total : null }; Код рабочий, но его всегда приходилось вспоминать или гуглить. Особенно если join не один, а два-три подряд. Теперь то же самое можно написать гораздо проще:
var query = context.Customers .LeftJoin( context.Orders, customer => customer.Id, order => order.CustomerId, (customer, order) => new { CustomerName = customer.Name, OrderId = order?.Id, Total = order?.Total }); Смысл читается сразу: берём всех Customers, справа подтягиваем Orders, а если совпадения нет — order будет null. Именно ради такой читаемости эти методы и ждали много лет. RightJoin работает зеркально: сохраняет все строки из правой последовательности. Это полезно в случаях, когда для вас главная сущность находится не слева, а справа. Пример: показать все заказы, даже если у заказа не найден клиент.
var query = context.Customers .RightJoin( context.Orders, customer => customer.Id, order => order.CustomerId, (customer, order) => new { OrderId = order.Id, CustomerName = customer != null ? customer.Name : "[deleted]" }); Где это особенно удобно:
• отчёты, где нужно сохранить все строки основной таблицы;
• админки и дашборды с необязательными связями;
• миграция старых LINQ-запросов, которые сейчас трудно читать и поддерживать. Ещё один сильный сценарий — цепочки из нескольких join’ов. Раньше такие запросы быстро превращались в визуальный лабиринт, а теперь остаются достаточно понятными.
var query = context.Orders .LeftJoin( context.Customers, order => order.CustomerId, customer => customer.Id, (order, customer) => new { order, customer }) .LeftJoin( context.Shippers, x => x.order.ShipperId, shipper => shipper.Id, (x, shipper) => new { OrderId = x.order.Id, CustomerName = x.customer?.Name ?? "[unknown]", ShipperName = shipper?.Name ?? "[not assigned]" }); Главная мысль простая: если раньше LEFT JOIN в LINQ выглядел как хак, то теперь он выглядит как нормальная операция языка запросов. Это не революция в производительности, а очень полезное улучшение читаемости, поддержки и обучения команды. @aStateOfNet