.NET中使用LINQ的Include关联3张表按OrderDate筛选的问题
问题根因
你遇到的问题有两个核心原因:
- 导航属性名称拼写错误:你在
ThenInclude中写的OrderNumberNavigation和实际模型中定义的ItemsInOrder.CustomerOrderNavigation名称不匹配,导致关联数据没有被正确加载 - 集合类型属性无法直接访问子属性:
Item.ItemsInOrders是ICollection<ItemsInOrder>集合类型,不能直接通过集合访问集合元素的属性,需要遍历集合元素或者做投影处理
修正方案
方案1:保留层级结构查询(适合需要嵌套数据的场景)
首先修正查询语句的导航属性名,按需添加OrderDate筛选逻辑:
// 示例:加载所有商品及其关联的订单中间表、订单主表数据,筛选2024年1月1日之后的订单关联商品 var query = _context.Items .Include(i => i.ItemsInOrders) .ThenInclude(io => io.CustomerOrderNavigation) .Where(i => i.ItemsInOrders.Any(io => io.CustomerOrderNavigation.OrderDate >= new DateTime(2024, 1, 1))) .ToList();
访问关联属性的方式:
foreach (var item in query) { Console.WriteLine($"商品名称:{item.ItemName}"); // 遍历当前商品关联的所有订单记录 foreach (var io in item.ItemsInOrders) { Console.WriteLine($"订单号:{io.OrderNumber},下单时间:{io.CustomerOrderNavigation.OrderDate:yyyy-MM-dd}"); } }
方案2:拍平查询结果(适合需要直接拿到所有关联字段的场景)
如果不需要嵌套结构,可以用SelectMany直接把关联结果拍平成自定义结构,不需要手动遍历嵌套集合:
var flatQuery = _context.Items .SelectMany(i => i.ItemsInOrders, (item, io) => new { 商品ID = item.ItemId, 商品名称 = item.ItemName, 订单号 = io.OrderNumber, 下单时间 = io.CustomerOrderNavigation.OrderDate }) .Where(res => res.下单时间 >= new DateTime(2024, 1, 1)) .ToList(); // 直接遍历就能拿到所有关联字段 foreach (var item in flatQuery) { Console.WriteLine($"{item.商品名称} {item.订单号} {item.下单时间:yyyy-MM-dd}"); }
内容的提问来源于stack exchange,提问作者Drakn
相关产品推荐
相关产品推荐

