实体框架核心3.1.1多级继承

时间:2020-02-03 15:38:43

标签: c# entity-framework-core table-per-hierarchy

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

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

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

Class Diagram

映射如下:

// 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);

Entity Framework Core 3.1.1是否支持“多级继承TPH”?

1 个答案:

答案 0 :(得分:4)

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

要应用于示例,需要删除DiscriminatorLevel2属性(列),从Internal枚举中删除CustomerType(假设InternalCustomer是抽象的)并合并RegularVIP放入其中,例如像这样的东西:

型号:

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>();

当您要查询InternalCustomer派生的实体时,可以使用db.Set<InternalCustomer>()db.Set<CustomerBase>().OfType<InternalCustomer>(),并且EF Core将应用类似于t.CustomerTypeId IN (1,2)的过滤器,即{{1} }子句将包含从IN派生的所有最终实体的鉴别符值的列表。