如何用EntityFramework方法语法改写LINQ Join查询并仅返回Order
问题描述
我有如下基于查询表达式的LINQ Join查询:
var orders = from o in DB.Orders join od in DB.OrderDetails on o.OrderId equals od.OrderId where od.Active == 1 && od.Date > dateFrom && od.StatusCode == 5 && o.CompanyId == companyId select o;
尝试改写为EntityFramework方法语法时卡在了投影部分,当前代码如下:
var orders = DB.Orders.Join(DB.OrderDetails, o => OrderId, od => OrderId, (o, od) => ...
希望仅检索完整的Order实体,但要通过OrderDetails的条件过滤,该怎么实现?
解决方案
方法一:完善Join写法
首先修正键选择器的错误(必须指定对象前缀),然后通过匿名类型临时携带Order和OrderDetail,过滤后再提取Order并去重:
var orders = DB.Orders .Join(DB.OrderDetails, o => o.OrderId, // 正确指定Order的OrderId od => od.OrderId, // 正确指定OrderDetail的OrderId (o, od) => new { Order = o, OrderDetail = od }) // 临时打包两者 .Where(x => x.OrderDetail.Active == 1 && x.OrderDetail.Date > dateFrom && x.OrderDetail.StatusCode == 5 && x.Order.CompanyId == companyId) .Select(x => x.Order) // 提取目标Order实体 .Distinct(); // 去重,避免同一Order匹配多条符合条件的OrderDetail时重复返回
方法二:利用导航属性(更简洁)
如果你的Order实体有导航属性OrderDetails(对应OrderDetail的集合),可以用Any替代Join,EF会自动转换为等价的查询:
var orders = DB.Orders .Where(o => o.CompanyId == companyId && o.OrderDetails.Any(od => od.Active == 1 && od.Date > dateFrom && od.StatusCode == 5));
这种写法更直观,代码量更少,推荐使用。
内容的提问来源于stack exchange,提问作者Shaggydog
相关产品推荐
相关产品推荐

