Entity Framework 使用 TPH 的多级继承
Multiple levels of inheritance with Entity Framework using TPH
我正在使用 Entity Framework 在现有遗留数据库上的新项目中创建 Table Per Heirachy 数据模型。这意味着我们不拥有数据库,因此我需要一个不涉及向 OrderDiscount table.
添加列的解决方案
我的数据模型中有以下结构:
┌────── (abstract) OrderDiscountBase ──────┐
│ │
│ │
SaleOrderDiscount ┌─── (abstract) SellerOrderDiscountBase ───┐
│ │
│ │
FreeShippingOrderDiscount PercentageValueOrderDiscount
有一个预先存在的鉴别器列来区分具体类型。它称为 DiscountType
,可以保存值 PercentageOffPromoDiscount
、FreeShippingPromoDiscount
或 SaleDiscount
。
我的项目中有以下映射,不幸的是,它不起作用。
private void ConfigureOrderDiscountEntity(EntityTypeConfiguration<OrderDiscountBase> entity)
{
entity
.HasKey(orderDiscount => orderDiscount.Id)
.Map<SaleOrderDiscount>(
configuration => configuration.Requires("DiscountType").HasValue(OrderDiscountTypes.Sale))
.Map<PercentageValueOrderDiscount>(
configuration => configuration.Requires("DiscountType").HasValue(OrderDiscountTypes.PercentageOff))
.Map<FreeShippingOrderDiscount>(
configuration => configuration.Requires("DiscountType").HasValue(OrderDiscountTypes.FreeShipping))
.ToTable(tableName: "OrderDiscount", schemaName: "Orders")
;
}
我看到的异常是:
EntityTypes SellerOrderDiscountBase、SaleOrderDiscount、FreeShippingOrderDiscount、PercentageValueOrderDiscount 被映射到 table OrderDiscountBase 中的相同行。映射条件可以用来区分这些类型映射到的行。
我看到人们在旧版本的 Entity Framework 中通过添加第二个鉴别器列解决了这个问题,但是,正如我所说,我无法对数据库进行更改。
我要求 EF 做的事情听起来并不难,所以我假设我只是错误地配置了我的实体。
在 EF 中绝对适合我 6.x:
public abstract class TPHBase
{
public int ID { get; set; }
public string CommonProperty { get; set; }
}
public class TPHChild1 : TPHBase
{
public string Child1Property { get; set; }
}
public abstract class TPHChild2 : TPHBase
{
public int? Child2Property { get; set; }
}
public class TPHChild3 : TPHChild2
{
public int? Child3Property { get; set; }
}
public class TPHChild4 : TPHChild2
{
public int? Child4Property { get; set; }
}
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
modelBuilder.Entity<TPHBase>()
.ToTable( "TPHBase" )
.Map<TPHChild1>( m => m.Requires( "Dyskryminator" ).HasValue( "c1" ) )
.Map<TPHChild3>( m => m.Requires( "Dyskryminator" ).HasValue( "c3" ) )
.Map<TPHChild4>( m => m.Requires( "Dyskryminator" ).HasValue( "c4" ) );
...
实体成功持久化,然后从数据库中检索。
我怀疑你发布的内容不多。
我正在使用 Entity Framework 在现有遗留数据库上的新项目中创建 Table Per Heirachy 数据模型。这意味着我们不拥有数据库,因此我需要一个不涉及向 OrderDiscount table.
添加列的解决方案我的数据模型中有以下结构:
┌────── (abstract) OrderDiscountBase ──────┐
│ │
│ │
SaleOrderDiscount ┌─── (abstract) SellerOrderDiscountBase ───┐
│ │
│ │
FreeShippingOrderDiscount PercentageValueOrderDiscount
有一个预先存在的鉴别器列来区分具体类型。它称为 DiscountType
,可以保存值 PercentageOffPromoDiscount
、FreeShippingPromoDiscount
或 SaleDiscount
。
我的项目中有以下映射,不幸的是,它不起作用。
private void ConfigureOrderDiscountEntity(EntityTypeConfiguration<OrderDiscountBase> entity)
{
entity
.HasKey(orderDiscount => orderDiscount.Id)
.Map<SaleOrderDiscount>(
configuration => configuration.Requires("DiscountType").HasValue(OrderDiscountTypes.Sale))
.Map<PercentageValueOrderDiscount>(
configuration => configuration.Requires("DiscountType").HasValue(OrderDiscountTypes.PercentageOff))
.Map<FreeShippingOrderDiscount>(
configuration => configuration.Requires("DiscountType").HasValue(OrderDiscountTypes.FreeShipping))
.ToTable(tableName: "OrderDiscount", schemaName: "Orders")
;
}
我看到的异常是:
EntityTypes SellerOrderDiscountBase、SaleOrderDiscount、FreeShippingOrderDiscount、PercentageValueOrderDiscount 被映射到 table OrderDiscountBase 中的相同行。映射条件可以用来区分这些类型映射到的行。
我看到人们在旧版本的 Entity Framework 中通过添加第二个鉴别器列解决了这个问题,但是,正如我所说,我无法对数据库进行更改。
我要求 EF 做的事情听起来并不难,所以我假设我只是错误地配置了我的实体。
在 EF 中绝对适合我 6.x:
public abstract class TPHBase
{
public int ID { get; set; }
public string CommonProperty { get; set; }
}
public class TPHChild1 : TPHBase
{
public string Child1Property { get; set; }
}
public abstract class TPHChild2 : TPHBase
{
public int? Child2Property { get; set; }
}
public class TPHChild3 : TPHChild2
{
public int? Child3Property { get; set; }
}
public class TPHChild4 : TPHChild2
{
public int? Child4Property { get; set; }
}
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
modelBuilder.Entity<TPHBase>()
.ToTable( "TPHBase" )
.Map<TPHChild1>( m => m.Requires( "Dyskryminator" ).HasValue( "c1" ) )
.Map<TPHChild3>( m => m.Requires( "Dyskryminator" ).HasValue( "c3" ) )
.Map<TPHChild4>( m => m.Requires( "Dyskryminator" ).HasValue( "c4" ) );
...
实体成功持久化,然后从数据库中检索。
我怀疑你发布的内容不多。