我有一个header-child表,子项具有不同的类型但存储在同一个表(TPH)中。
除此之外,用户可以对标题及其子记录的副本进行快照,并且我希望将捕捉的副本存储到不同的表中,因为这些快照记录的查看/修改频率较低。
为实现这一目标,我将TPC与现有的TPH混合。
新结构如下:
public class Header
{
private IList<Child> _childs = new List<Child>();
private IList<ChildSnapshot> _childSnapshots = new List<ChildSnapshot>();
[Key]
public int Id { get; set; }
public string Name { get; set; }
public IList<Child> Childs { get { return _childs; } }
public IList<ChildSnapshot> ChildSnapshots { get { return _childSnapshots; } }
}
public abstract class ChildBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("Header")]
public int HeaderId { get; set; }
[ForeignKey("HeaderId")]
public virtual Header Header { get; set; }
}
public abstract class Child : ChildBase
{
}
public class Child1 : Child
{
}
public class Child2 : Child
{
}
public abstract class ChildSnapshot : ChildBase
{
}
public class ChildSnapshot1 : ChildSnapshot
{
}
public class ChildSnapshot2 : ChildSnapshot
{
}
数据库上下文:
public class TestContext : DbContext
{
public DbSet<Header> Headers { get; set; }
public DbSet<Child> Childs { get; set; }
public DbSet<ChildSnapshot> ChildSnapshots { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Header>().Map(m => m.ToTable("Header"));
modelBuilder.Entity<Child>()
.Map<Child>(m =>
{
m.MapInheritedProperties();
m.ToTable("Child");
})
.Map<Child1>(m =>
{
m.Requires("Discriminator").HasValue("Child1");
})
.Map<Child2>(m =>
{
m.Requires("Discriminator").HasValue("Child2");
});
modelBuilder.Entity<ChildSnapshot>()
.Map<ChildSnapshot>(m =>
{
m.MapInheritedProperties();
m.ToTable("ChildSnapshot");
})
.Map<ChildSnapshot1>(m =>
{
m.Requires("Discriminator").HasValue("Child1");
})
.Map<ChildSnapshot2>(m =>
{
m.Requires("Discriminator").HasValue("Child2");
});
}
}
经过多次试验和错误后,它完美无缺。但是,我必须在Header类中创建2个列表属性。是否可以只有1个ChildBase类型的列表属性?我这样做时出现了以下错误。
“Child”类型无法按定义映射,因为它映射了继承 来自使用实体拆分或其他形式的类型的属性 遗产。或者选择不同的继承映射策略 至于不映射继承的属性,或更改中的所有类型 层次结构,用于映射继承的属性,不使用拆分。
为什么行为由容器列表的类型决定?不能EF从列表中的对象类型推断出来吗?
仅供参考我使用的是EF 4.3。