我正在尝试使用Entity Framework 6 Code First实现TPH继承,并且我的继承类型与关系存在问题。
我的代码是
public abstract class Base...
public class Inherited1 : Base
{
public virtual Type1 Rel { get; set; }
...
public class Inherited2 : Base
{
public virtual Type1 Rel {get;set;}
...
所以继承的类型具有“相同”的关系。继承本身工作正常,但我遇到的问题是与表Type1的关系将被添加两次(逻辑...)而另一个关系是从Inherited2.Id到Type1.Id而不是Inherited2.Type1Id到Type1.Id第一个关系是(正确)。
我不确定我是否有任何意义解释这个以及更改类型名称的部分代码示例,但我希望你明白这一点。如果您需要,请询问更多详细信息。
我可能可以使用
正确实现这一点 更新
我已经创建了一个示例Github repo来演示这个问题。随意告诉我我做错了什么。 https://github.com/antsim/EntityFrameworkTester
答案 0 :(得分:2)
尝试使用以下
1-如果你想要TPT
modelBuilder.Entity<Inherited1>()
.ToTable("Inherited1s")
.HasKey(x => x.YourKey)
.HasRequired(x=>Type1)
.WithMany()
.HasForeignKey(x=>Type1Id)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Inherited2>()
.ToTable("Inherited2s")
.HasKey(x => x.YourKey)
.HasRequired(x=>Type1)
.WithMany()
.HasForeignKey(x=>Type1Id)
.WillCascadeOnDelete(false);
2 - 如果你想要TPH
modelBuilder.Entity<Base>()
.ToTable("YourTableName")
.HasRequired(m=>m.Type1)
.WithMany()
.HasForeignKey(m=>m.Type1Id)
.WillCascadeOnDelete(); // true or false as you want
有关详细信息,请查看此article
基于您提供的样本
Attachment
和Document
继承自File,您使用的是TPH
,这意味着将使用Discriminator
字段创建一个表。Document
和FileContainer
的关系类型为0..1,这意味着应在FileContainerId
中创建外键Document
,因此File
} table FileContainer
和Attachment
的关系类型为0..n,然后将在表File 在您提供的示例中,我进行了以下更改
对TestContext所做的更改是
modelBuilder.Entity<FileContainer>()
.HasOptional(x => x.Document)
.WithMany()
.HasForeignKey(t => t.DocumentId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Document>()
.HasRequired(t => t.FileContainer)
.WithMany()
.HasForeignKey(t => t.FileContainerId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Attachment>()
.HasRequired(t => t.FileContainer)
.WithMany()
.HasForeignKey(t => t.FileContainerAttachmentId)
.WillCascadeOnDelete(false);
输出正确(文件表包含鉴别器字段以及两个关系,一个用于带有容器的文档,另一个用于带容器的附件)。
我认为更好的解决方案是:
FileType ( Id, Name)
,Attachment
的课程Document
,并将其添加为File
FileContainer
和File
希望这会对你有所帮助