EF Core中ThenInclude加载Effort.Parent时抛出异常求助
问题描述
编写了如下EF Core查询代码,尝试通过Include和ThenInclude加载AppUser关联的Signup.Effort.Parent数据:
var user = await context.AppUsers .Include(user => user.Following!) .ThenInclude(org => org.News) .Include(user => user.Interests) .Include(user => user.Signups!) .ThenInclude(signup => signup.Effort) .ThenInclude(effort => effort.Parent) .FirstOrDefaultAsync(user => user.Id == _combinedUser.AppUser.Id);
当移除ThenInclude(effort => effort.Parent)时查询正常执行,保留该语句则抛出System.InvalidOperationException异常,异常提示表达式effort.Parent在Include操作中无效,需针对派生类型使用转换。
相关实体类结构如下:
public class Signup : IAuditTrail, IPrimaryEntities, IDisableable { public Effort Effort { get; set; } public int EffortId { get; private set; } } public abstract class Effort : IAuditTrail, IPrimaryEntities, IDisableable { public Organization Parent { get; set; } public int ParentId { get; private set; } public List<Signup>? Signups { get; set; } } public class Event : Effort { } public class Organization : IPrimaryEntities, IAuditTrail, IDisableable { public List<Event>? Events { get; private set; } }
问题原因与解决方法
原因
EF Core无法直接对抽象基类的导航属性使用ThenInclude。因为抽象类本身不会映射到数据库表,实际存储的是它的派生类(此处为Event)。当尝试包含抽象类Effort的Parent属性时,EF Core无法确定具体要加载哪个派生类的关联数据,因此抛出异常要求指定派生类型。
解决方法
需要在ThenInclude中通过OfType<派生类>或Cast<派生类>明确指定具体的派生类型,再加载其导航属性。修改后的查询代码如下:
var user = await context.AppUsers .Include(user => user.Following!) .ThenInclude(org => org.News) .Include(user => user.Interests) .Include(user => user.Signups!) .ThenInclude(signup => signup.Effort.OfType<Event>()) .ThenInclude(effort => effort.Parent) .FirstOrDefaultAsync(user => user.Id == _combinedUser.AppUser.Id);
若所有Effort的实例都是Event,也可以用Cast<Event>:
var user = await context.AppUsers .Include(user => user.Following!) .ThenInclude(org => org.News) .Include(user => user.Interests) .Include(user => user.Signups!) .ThenInclude(signup => signup.Effort.Cast<Event>()) .ThenInclude(effort => effort.Parent) .FirstOrDefaultAsync(user => user.Id == _combinedUser.AppUser.Id);
这样EF Core就能明确知道要加载Event类型的Parent关联数据,避免异常。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

