2015-12-06 68 views
0

在我的业务领域中,我有两个实体,它们作为对象根据它们公开的属性定义了层次关系,但是在数据库层面它们有很大不同。实体框架 - 如何避免类层次结构中的TPC

具体来说,我所拥有的是一个Image类,它定义了属性A和B(在Id旁边)以及几个简单的方法。 然后我有一个Thumbnail类,它和Image完全一样。

在OOP视角内,使缩略图从Image继承是合乎逻辑的。但是,在Db级别,这两个实体在一个重要的细节上有所不同: 图像将FK声明到另一个表格,而不是Thumbnail。

实际上,Image定义了产品(例如)可以具有的(多对一)图像集,但缩略图定义了同一产品可以具有的唯一缩略图(一对一或零对一)。在这种情况下,缩略图将不在图像集中。

因此,在DB中,图像表应该有列A,B,Id和FK到产品,而缩略图表应该只有列A,B和Id(这也将是产品的FK)。

如果我使用EF Code First对其进行建模,充其量(最多可以)为图像生成一个表格,然后为图像和缩略图之间的缩略图和一对一或零对一关联生成一张表格。这种关联是我试图避免的,因为添加缩略图我还必须将它添加为图像,然后设置FK,这是不可能的,因为它没有。

如果我明确指定生成TPC,那么它不允许我在Product和Image之间建立关联,因为关联应该只在大多数派生类型中定义。

你有什么想法吗?

+0

您可以尝试使图像从Thumbnail继承。通过这种方式,您可以只在图像中设置FK,而不是在缩略图中设置。不知道这是否是你问题的解决方案,但是如果两个类完全相同,则可以“交换”关系。 – Koosshh56

+0

@ Koosshh56,这将无法正常工作。如果我想为缩略图添加其他属性呢?缩略图将永远是一个图像,但它也是一个更严格的图像案例。我想要告诉EF忽略从图像继承的缩略图,如果我必须手动映射所有属性或其他内容,则无关紧要。 – mdarefull

+0

我不得不做类似的事情。试着看看[这个视频教程](https://www.youtube.com/watch?v=-tMX36hRSsU&list=PL6n9fhu94yhUPBSX-E2aJCnCR3-_6zBZx&index=21) – Koosshh56

回答

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);