如何使用Linq过滤父实体中匹配查询条件的子实体
这个需求没法仅通过查询父实体实现,必须额外对子实体做过滤处理。
你当前写的dtos.Where(a=>a.Items.Any(x=>x.Value == 8))逻辑,仅能筛选出「存在至少一个符合条件子项的父Dto」,并不会修改父Dto内部的Items集合内容,返回的Dto仍然会携带所有子项。另外你的示例代码还有执行顺序错误:你是先执行了dtos的查询逻辑,之后才往dtos里添加数据,最终dtos2必然查不到任何结果。
正确的实现方式参考如下:
内存中处理已加载的Dto集合
using System; using System.Linq; using System.Collections.Generic; public class Program { public static void Main() { List<Dto> dtos = new List<Dto>(); var items = new List<Item> { new Item(){ Value = 5}, new Item(){ Value = 6}, new Item(){ Value = 8} }; dtos.Add(new Dto() { Id = 1, Items = items }); // 先筛选出Id为1的父Dto var targetDto = dtos.FirstOrDefault(a => a.Id == 1); if (targetDto != null) { // 手动过滤符合条件的子项,生成新Dto避免修改原数据 var result = new Dto { Id = targetDto.Id, Items = targetDto.Items.Where(x => x.Value == 8).ToList() }; Console.WriteLine(result.Id); foreach(var item in result.Items) { Console.WriteLine(item.Value); } } } public class Dto { public int Id {get;set;} public List<Item> Items {get;set;} } public class Item { public int Value {get;set;} } }
如果你是用EF Core查询数据库的场景
EF Core 5.0及以上版本支持Filtered Include语法,可以直接在查询时过滤关联子集合,不需要手动在内存处理:
var result = context.Dtos .Include(d => d.Items.Where(i => i.Value == 8)) .FirstOrDefault(d => d.Id == 1);
内容的提问来源于stack exchange,提问作者mko
相关产品推荐
相关产品推荐

