EF Core 包含抽象派生类上的导航属性

时间:2021-06-23 13:45:37

标签: c# entity-framework entity-framework-core ef-core-3.1

在尝试包含派生类型的导航属性时,我收到以下异常:

System.InvalidOperationException: Invalid include.
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.PopulateIncludeTree(IncludeTreeNode includeTreeNode, Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ProcessInclude(NavigationExpansionExpression source, Expression expression, Boolean thenInclude)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   ...

使用以下简化的类结构:

public abstract class BaseJob
{
  public int Id { get; set; }
}
public abstract class WorkerJob : BaseJob
{
  public Person Person { get; set; }
}
public class PaintingJob : WorkerJob
{
  public string Color { get; set; }
}
public class Person {
  public int Id { get; set; }
  public string Name { get; set; }
}

当通过 DbContext 进行查询时,如记录的 here

// Throws InvalidOperationException
var jobs = await _context.BaseJobs
  .Include(job => (job as WorkerJob).Person) // WorkerJob is abstract
  .ToListAsync();

这必须与抽象类中存在的导航属性相关,因为将查询调整为按预期工作:

// Works as intended
var jobs = await _context.BaseJobs
  .Include(job => (job as PaintingJob).Person) // PaintingJob is concrete
  .ToListAsync();

但是,我有许多具体的派生类,我不想每次添加新的具体类时都必须更改查询。这可能是 EF Core 的错误,还是我做错了什么?

1 个答案:

答案 0 :(得分:2)

绝对不是错误,错误是我的。我错误地配置了上下文如下:

modelBuilder.Entity<PaintingJob>(entity =>
  {
    entity.HasBaseType<WorkerJob>();
    entity.HasOne(x => x.Person)
      .WithMany()
      .HasForeignKey(x => x.PersonId);
  });

在定义导航属性时将其更改为使用抽象类可解决引发的异常并按预期返回结果。

modelBuilder.Entity<WorkerJob>(entity =>
  {
    entity.HasBaseType<BaseJob>();
    entity.HasOne(x => x.Person)
      .WithMany()
      .HasForeignKey(x => x.PersonId);
  });