You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 14:47:14