使用不同的包含查询基础和子类型

问题描述

我有一个类型和子类型

public class Reservation
{
   public int Id {get; set;}
   public TimeSpan Length {get; set;}
}
public class Appointment : Reservation
{
   public Customer Customer {get; set;}
}

数据库上下文

public DbSet<Reservation> Reservations { get; set; }
public DbSet<Appointment> Appointments { get; set; }

每个层次结构表 (TPH) 是当前设置,因为它是 ef core 3.1 的唯一选项。

现在我想查询超集 Reservations 并在 CustomerReservation 时包含 Appointment。我试着像这样在 union 上使用 IQueryable

var reservations = context.Appointments.Include(e => e.Customer)
                   .Union(context.Reservations)

但我明白

InvalidOperationException: '当执行一个集合操作时, 操作数必须具有相同的包含操作

虽然可以在内存中执行 Union。我想执行一次可以节省一天的行程查询。如果只存在解决方案,我可能会迁移到 EntityFramework core 5

编辑:https://github.com/dotnet/efcore/issues/16298

解决方法

我建议使用这种方法,不确定它是否适用于 EF Core,因为它在使用 Concat/Union 时存在问题。此外,您的案例需要 Concat - UNION ALL,而不是 Union - UNION

var query1 = 
    context.Appointments.Select(e => new Appointment
    {
        Id = e.Id,Length = e.Length,Cutomer = e.Customer 
    });

 var query2 = 
    context.Reservations.Select(e => new Appointment
    {
        Id = e.Id,}); 

var query = query1.Concat(query2);

如果你需要具体的类,你必须在客户端进行转换。在 ChangeTracker 中也只有客户。