EF Core筛选Include在映射新对象时为何未按预期生效?
问题原因解析
这是EF Core(Entity Framework Core)中Include筛选和**投影(Select)**的逻辑优先级导致的问题,具体原因如下:
1. 第一种写法:Include中加筛选被忽略的原因
EF Core里的Include(x => x.Units.Where(u => u.IsActive))属于过滤式Include,它的作用是:当EF加载Plant实体的Units导航属性时,只加载符合IsActive=true的记录,但这个逻辑仅针对实体本身的导航属性加载。
而你后续使用了Select做投影,直接构造PlantGridDTO并取x.Units——此时EF Core会认为你要的是Plant实体关联的原始Units集合(因为投影是直接从实体对象取数据),会忽略之前Include里的过滤条件,最终生成的SQL就是普通的左连接,没有筛选。
简单说:Include的过滤是给实体导航属性用的,投影阶段不会继承这个过滤逻辑。
2. 第二种写法:投影中筛选生效的原因
当你把Units.Where(u => u.IsActive)放到Select的投影里时,这是在明确告诉EF Core:我要的DTO里的Units是过滤后的集合。EF会直接把这个过滤逻辑翻译成SQL的子查询,先筛选出IsActive=true的Unit记录,再和Plant做关联,所以生成的SQL符合预期。
额外补充
如果想让Include的过滤在投影中生效,你需要确保投影是基于被Include过滤后的实体导航属性,但EF Core的查询解析逻辑里,投影会优先重新解析集合表达式,所以更可靠的写法就是第二种:直接在投影里过滤集合。
内容的提问来源于stack exchange,提问作者Homer
相关产品推荐
相关产品推荐

