在我的业务领域,我有两个实体,作为对象,根据它们公开的属性定义层次关系,但在数据库级别它们是非常不同的。
具体来说,我所拥有的是一个Image类,它定义了属性A和B(在Id旁边),以及几个简单的方法。 然后我有一个Thumbnail类,它与Image完全相同。
在OOP透视图中,使Thumbnail从Image继承是合乎逻辑的。但是,在Db级别,这两个实体在一个重要细节上有所不同: 图像将FK声明为另一个表而缩略图不是。
实际上,Image定义了Product(例如)可以拥有的图像集(Many-to-One),但Thumbnail定义了同一产品可以拥有的唯一缩略图(One-or-Zero-to-One) 。在这种情况下,缩略图不会出现在图像集中。
因此,在数据库中,Image表应该有列A,B,Id和FK到Product,而Thumbnail表应该只有列A,B和Id(也是FK到Product)。 / p>
如果我使用EF Code First对此进行建模,最好(尽可能)它为Image生成一个表,然后为Thumbnail生成一个表,在Image和Thumbnail之间生成一对一或从零到一的关联。这种关联是我试图避免的,因为添加缩略图我还必须将其添加为图像,然后设置FK,这是不可能的,因为它没有。
如果我明确指定生成TPC,那么它不允许我在Product和Image之间建立关联,因为关联只能在大多数派生类型中定义。
你有什么想法吗?
答案 0 :(得分:2)
您需要配置实体,以便他们使用Mapping the Table-Per-Concrete Class (TPC) Inheritance:
在TPC映射方案中,层次结构中的所有非抽象类型都映射到各个表。映射到派生类的表与映射到数据库中的基类的表没有关系。类的所有属性(包括继承的属性)都映射到相应表的列。
这是使用TPC ::
的可能配置的示例modelBuilder.Entity<Image>()
.Property(c => c.ImageID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<ThumbNail>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Thumbnails");
});
为了您的特定目的,您必须对其进行微调。例如,使用以下内容排除FK属性:
modelBuilder.Entity<Thumbnail>().Ignore(p => p.FkProperty);