C# 实体框架核心3.1.1多级继承

C# 实体框架核心3.1.1多级继承,c#,entity-framework-core,table-per-hierarchy,C#,Entity Framework Core,Table Per Hierarchy,运行添加迁移时引发异常(EF core 3.1.1): 无法将CLR属性“DiscriminatorLevel2Id”添加到实体类型“CustomerBase”,因为它是在CLR类型“InternalCustomer”上声明的 下图显示了所需的层次结构(简要): 映射看起来像: // Discriminator (Level 1) modelBuilder.Entity<CustomerBase>() .HasDiscrimina

运行添加迁移时引发异常(EF core 3.1.1):

无法将CLR属性“DiscriminatorLevel2Id”添加到实体类型“CustomerBase”,因为它是在CLR类型“InternalCustomer”上声明的

下图显示了所需的层次结构(简要):

映射看起来像:

// Discriminator (Level 1)
modelBuilder.Entity<CustomerBase>()              
            .HasDiscriminator(b => b.CustomerTypeId)
            .HasValue<InternalCustomer>((int)CustomerType.Internal)
            .HasValue<ExternalCustomer>((int)CustomerType.External);

// Discriminator (Level 2)
modelBuilder.Entity<InternalCustomer>()
         .HasDiscriminator(b => b.DiscriminatorLevel2Id)
         .HasValue<VIPCustomer>((int)DiscriminatorLevel2.VIP)
         .HasValue<RegularCustomer>((int)DiscriminatorLevel2.Regular);
//鉴别器(1级)
modelBuilder.Entity()
.HasDiscriminator(b=>b.CustomerTypeId)
.HasValue((int)CustomerType.Internal)
.HasValue((int)CustomerType.External);
//鉴别器(二级)
modelBuilder.Entity()
.HasDiscriminator(b=>b.DiscriminatorLevel2Id)
.HasValue((int)鉴别器level2.VIP)
.HasValue((int)鉴别器level2.Regular);

实体框架核心3.1.1支持“多级继承TPH”吗?

这是可能的,但在根抽象级别使用单个共享鉴别器,其中包含所有可能的可创建(非抽象)直接或间接派生实体的值

应用于您的示例需要删除
DiscriminatorLevel2
属性(列),从
CustomerType
枚举中删除
Internal
(假设
InternalCustomer
是抽象的),并将
常规
VIP
合并到其中,例如:

型号:

配置:

modelBuilder.Entity()
.HasDiscriminator(b=>b.CustomerTypeId)
.HasValue((int)CustomerType.External)
.HasValue((int)CustomerType.VIP)
.HasValue((int)CustomerType.Regular);
modelBuilder.Entity();

当您想要查询
InternalCustomer
派生实体时,您可以使用
db.Set()
db.Set().OfType()
,EF Core将应用与(1,2)
中的
t.CustomerTypeId类似的过滤器,也就是说,
子句中的
将包含从
InternalCustomer
派生的所有最终实体的鉴别器值列表

多级鉴别器-否。带公共鉴别器的多级继承-是。感谢Ivan Foster,“带公共鉴别器的多级继承”是如何实现的,在上面的例子中需要做哪些更改?非常感谢,感谢您的回答
public abstract class CustomerBase
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CustomerTypeId { get; set; }
}

public abstract class InternalCustomer : CustomerBase
{
    public decimal Points { get; set; }
}

public class RegularCustomer : InternalCustomer
{
    public int PartnerId { get; set; }
}

public class VIPCustomer : InternalCustomer
{
    public string CardNo { get; set; }
}

public class ExternalCustomer : CustomerBase
{
}

public enum CustomerType { External, Regular, VIP }
modelBuilder.Entity<CustomerBase>()
    .HasDiscriminator(b => b.CustomerTypeId)
    .HasValue<ExternalCustomer>((int)CustomerType.External)
    .HasValue<VIPCustomer>((int)CustomerType.VIP)
    .HasValue<RegularCustomer>((int)CustomerType.Regular);

modelBuilder.Entity<InternalCustomer>();