如何在LINQ左外连接中返回含订单列表的CustomerDto?
LINQ左外连接实现客户-订单列表映射
需求说明
需要通过LINQ实现左外连接查询,关联Customer和Order表,最终返回CustomerDto类型的结果:
- 每个客户对应一条记录
- 有订单的客户,其
CustomerOrderList字段包含该客户的所有订单 - 无订单的客户,
CustomerOrderList为空数组
当前编写的查询会为每个订单生成一条客户记录,不符合“每个客户一条记录”的要求,需要调整。
数据表结构
表:Customer
CustomerId | Name 1 | John Smith 2 | Peter James
表:Order
id | CustomerId | Total 1 | 1 | $100 2 | 1 | $200
CustomerDto定义
public class CustomerDto { public long CustomerId { get; set; } public string Name{ get; set; } public CustomerOrder[] CustomerOrderList{ get;set;} }
当前问题代码
IQueryable<CustomerDto> search = from customer in _database.Customer join customerOrder in _database.CustomerOrder on customer.CustomerId equals customerOrder.CustomerId into CS from subCustomerSale in CS.DefaultIfEmpty() select new CustomerDto { CustomerId = customer.CustomerId, Name = customer.Name, CustomerOrderList = subCustomerSale };
解决方案
问题出在from subCustomerSale in CS.DefaultIfEmpty()这一步——它会把分组后的订单集合展开,导致每个订单对应一条客户记录。正确的做法是直接使用分组后的集合,将其转换为数组赋值给CustomerOrderList:
IQueryable<CustomerDto> search = from customer in _database.Customer join customerOrder in _database.CustomerOrder on customer.CustomerId equals customerOrder.CustomerId into customerOrdersGroup select new CustomerDto { CustomerId = customer.CustomerId, Name = customer.Name, // 将分组后的订单集合转为数组,无订单时自动为空数组 CustomerOrderList = customerOrdersGroup.ToArray() };
说明
join ... into customerOrdersGroup会将每个客户对应的所有订单分组到customerOrdersGroup集合中- 直接调用
customerOrdersGroup.ToArray():有订单时返回订单数组,无订单时返回空数组,完全符合需求 - 不需要额外的
DefaultIfEmpty(),因为分组集合本身对于无订单的客户就是空集合,ToArray()会自动处理为空数组
内容的提问来源于stack exchange,提问作者Sami.C
相关产品推荐
相关产品推荐

