含多类型连接的SQL转LINQ求助:混合内连接与左连接实现
混合连接类型的SQL转LINQ实现
针对你提供的SQL查询,以下是对应的LINQ查询语法和方法语法实现,完美匹配原SQL的内连接、左连接、过滤、分组和排序逻辑:
一、LINQ查询语法(推荐,可读性高)
var query = from oh in OrderHeader // 应用WHERE条件过滤订单头 where oh.DeliveryDate == new DateTime(2023, 3, 2) // 注意:原SQL日期格式需确认,此处按DD/MM/YYYY处理 && oh.OrderType == "Web" // 内连接OrderDetail(和你熟悉的单一内连接写法一致) join od in OrderDetail on oh.OrderId equals od.OrderId // 左连接Customer:用into+DefaultIfEmpty实现左外连接 join c in Customer on oh.CustomerId equals c.Id into customerGroup from c in customerGroup.DefaultIfEmpty() // 左连接ItemAvailability join ia in ItemAvailability on od.ItemId equals ia.RecId into iaGroup from ia in iaGroup.DefaultIfEmpty() // 过滤掉ItemAvailability为空的行(对应原SQL中后续的INNER JOIN Inventory逻辑) where ia != null // 内连接Inventory join ivt in Inventory on ia.ItemId equals ivt.ItemId // 按指定字段分组,同时聚合Quantity group new { od.Quantity, c.DeliveryMethod } by new { ia.ItemId, ivt.ItemName, DeliveryMethod = c.DeliveryMethod // 对应原SQL的C.DeliveryMethod,修正原SQL GROUP BY的笔误 } into g // 按ItemId排序 orderby g.Key.ItemId // 选择最终结果 select new { g.Key.ItemId, g.Key.ItemName, g.Key.DeliveryMethod, Qty = g.Sum(x => x.Quantity) };
二、LINQ方法语法(供参考)
var queryMethodSyntax = OrderHeader .Where(oh => oh.DeliveryDate == new DateTime(2023, 3, 2) && oh.OrderType == "Web") // 内连接OrderDetail .Join(OrderDetail, oh => oh.OrderId, od => od.OrderId, (oh, od) => new { oh, od }) // 左连接Customer:GroupJoin+SelectMany+DefaultIfEmpty .GroupJoin(Customer, x => x.oh.CustomerId, c => c.Id, (x, customerGroup) => new { x.oh, x.od, customerGroup }) .SelectMany(x => x.customerGroup.DefaultIfEmpty(), (x, c) => new { x.oh, x.od, c }) // 左连接ItemAvailability .GroupJoin(ItemAvailability, x => x.od.ItemId, ia => ia.RecId, (x, iaGroup) => new { x.oh, x.od, x.c, iaGroup }) .SelectMany(x => x.iaGroup.DefaultIfEmpty(), (x, ia) => new { x.oh, x.od, x.c, ia }) // 过滤ItemAvailability为空的行 .Where(x => x.ia != null) // 内连接Inventory .Join(Inventory, x => x.ia.ItemId, ivt => ivt.ItemId, (x, ivt) => new { x.ia, ivt, x.c, Quantity = x.od.Quantity }) // 分组聚合 .GroupBy(x => new { x.ia.ItemId, x.ivt.ItemName, x.c.DeliveryMethod }) // 排序 .OrderBy(g => g.Key.ItemId) // 选择结果 .Select(g => new { g.Key.ItemId, g.Key.ItemName, g.Key.DeliveryMethod, Qty = g.Sum(x => x.Quantity) });
关键说明
- 左连接实现:LINQ查询语法中通过
join ... into ...配合from ... in ...DefaultIfEmpty()实现左外连接,方法语法中则用GroupJoin+SelectMany+DefaultIfEmpty完成相同逻辑。 - 混合连接处理:先完成左连接后,通过
where ia != null过滤掉空数据,再执行内连接,完全匹配原SQL中LEFT JOIN ItemAvailability后INNER JOIN Inventory的逻辑。 - 日期处理:避免直接使用字符串日期,转为
DateTime对象可避免格式兼容问题,需根据实际业务确认日期格式(原SQL的'02/03/2023'是DD/MM还是MM/DD)。 - 分组修正:原SQL中
GROUP BY C.DlvMode应为笔误,对应SELECT中的C.DeliveryMethod,LINQ中统一使用DeliveryMethod字段保证逻辑一致。
内容的提问来源于stack exchange,提问作者Conax
相关产品推荐
相关产品推荐

