实体框架-如何避免类层次结构中的TPC

本文关键字:层次结构 TPC 何避免 框架 实体 | 更新日期: 2023-09-27 18:26:03

在我的业务域中,我有两个实体,作为对象,根据它们公开的属性定义层次关系,但在数据库级别,它们非常不同。

具体来说,我有一个Image类,它定义了属性A和B(在Id旁边),以及几个简单的方法。然后我有一个缩略图类,它与图像完全相同。

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

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

因此,在DB中,Image表应该有A、B、Id列和FK到Product列,而Thumbnail表应该只有A、B和Id列(这也将是FK到Product.)。

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

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

你有什么想法吗?

实体框架-如何避免类层次结构中的TPC

您需要配置实体,以便它们使用映射每个具体类的表(TPC)继承:

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