EF Core 8中基于父实体条件实现ThenInclude关联过滤
可行解决方案
由于EF Core原生Include默认会加载所有关联数据,要实现按Project.Type过滤关联Task,有两种可靠方式:
1. 投影构造目标对象(兼容所有EF Core版本)
通过Select投影到匿名类型或自定义DTO,在投影过程中对Task进行条件过滤:
query.Select(p => new { 项目 = p, 里程碑 = p.Milestones.Select(m => new { 里程碑实体 = m, 符合规则的任务 = m.Tasks.Where(t => (p.Type == "A" && (t.Gender == "X" || t.Gender == "Y")) || (p.Type == "B" && (t.Gender == "One" || t.Gender == "Two")) ).Select(t => new { 任务实体 = t, 子任务 = t.SubTasks }) }) }).AsSplitQuery();
如果需要返回原始实体类型,可在投影时重新实例化实体对象,这种方式适合只读场景,避免实体跟踪带来的问题。
2. 使用EF Core 5+的过滤式Include(推荐)
EF Core 5及更高版本支持在Include链中直接对关联集合加Where过滤,写法更简洁:
query .Include(p => p.Milestones) .ThenInclude(m => m.Tasks.Where(t => (p.Type == "A" && (t.Gender == "X" || t.Gender == "Y")) || (p.Type == "B" && (t.Gender == "One" || t.Gender == "Two")) )) .ThenInclude(t => t.SubTasks) .AsSplitQuery();
EF Core会自动解析外层的p.Type条件,生成正确的SQL语句过滤不符合规则的Task,同时保留关联的SubTask。
关于IncludeIf的说明
EF Plus的IncludeIf仅用于控制是否加载整个关联集合,无法过滤集合内的元素,所以之前尝试的方案不适用当前需求。
内容的提问来源于stack exchange,提问作者Jose Luis Suarez Cabrera
相关产品推荐
相关产品推荐

