Entity Framework核心3.1.1多级继承
Entity Framework core 3.1.1 Multilevel Inheritance
添加迁移(EF 核心 3.1.1)时抛出异常:
CLR property 'DiscriminatorLevel2Id' cannot be added to entity type 'CustomerBase' because it is declared on the CLR type '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);
Entity Framework Core 3.1.1 是否支持 "Multilevel Inheritance TPH"?
这是可能的,但是在包含所有可能的可创建(非抽象)直接或间接派生实体的值的根抽象级别上使用单个共享鉴别器。
应用于您的示例需要删除 DiscriminatorLevel2
属性(列),从 CustomerType
枚举中删除 Internal
(假设 InternalCustomer
是抽象的)和将 Regular
和 VIP
合并到其中,例如像这样:
型号:
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)
的过滤器,即 IN
子句将包含来自 InternalCustomer
.
的所有最终实体的鉴别器值列表
添加迁移(EF 核心 3.1.1)时抛出异常:
CLR property 'DiscriminatorLevel2Id' cannot be added to entity type 'CustomerBase' because it is declared on the CLR type '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);
Entity Framework Core 3.1.1 是否支持 "Multilevel Inheritance TPH"?
这是可能的,但是在包含所有可能的可创建(非抽象)直接或间接派生实体的值的根抽象级别上使用单个共享鉴别器。
应用于您的示例需要删除 DiscriminatorLevel2
属性(列),从 CustomerType
枚举中删除 Internal
(假设 InternalCustomer
是抽象的)和将 Regular
和 VIP
合并到其中,例如像这样:
型号:
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)
的过滤器,即 IN
子句将包含来自 InternalCustomer
.