EF Core 5中Include带Where筛选后接ThenInclude的继承问题
歧义报错原因
当你在Include方法中对集合属性添加Where过滤条件后,返回的IIncludableQueryable泛型参数为IEnumerable<Warehouse>,编译器无法判断ThenInclude的重载是针对集合本身,还是针对集合内的单个元素,因此触发了二义性错误。
解决方案
方案1:显式指定ThenInclude泛型参数
直接显式声明ThenInclude的三个泛型类型,告诉编译器我们要遍历的是集合内的单个Warehouse元素,即可消除歧义,该方案代码改动最小,适用于EF Core 5+版本:
public IQueryable<User> GetUsers() { return this.DbContext.Users .Include(u => u.Warehouses.Where(wh => wh.IsActive)) // 泛型参数依次为:源实体类型、集合元素类型、要加载的关联属性类型 .ThenInclude<User, Warehouse, User>(wh => ((ManagedWarehouse)wh).GeneralManager); }
EF Core可自动识别类型转换逻辑,生成的SQL会为ManagedWarehouse做左连接关联管理员表,不会返回多余数据。
方案2:使用投影查询(兼容所有EF Core版本)
如果你使用的EF Core版本低于5,不支持Include内过滤,或者想要更明确控制返回结构,可以使用投影查询手动映射结果,不需要依赖Include/ThenInclude,从根源避免重载歧义:
public IQueryable<User> GetUsers() { return this.DbContext.Users .Select(u => new User { UserId = u.UserId, Name = u.Name, Warehouses = u.Warehouses .Where(wh => wh.IsActive) .Select(wh => // 针对ManagedWarehouse单独加载关联属性 wh is ManagedWarehouse mw ? new ManagedWarehouse { WarehouseId = mw.WarehouseId, IsActive = mw.IsActive, GeneralManagerId = mw.GeneralManagerId, GeneralManager = mw.GeneralManager } : new Warehouse { WarehouseId = wh.WarehouseId, IsActive = wh.IsActive }).ToList() }); }
内容的提问来源于stack exchange,提问作者Trecius Veil
相关产品推荐
相关产品推荐

