Entity Framework - 如何在 class 层次结构中避免 TPC
Entity Framework - How to avoid TPC in a class hierarchy
在我的业务领域中,我有两个实体,作为对象,它们根据它们公开的属性定义层次关系,但在数据库级别上它们非常不同。
具体来说,我有一个图像 class,它定义了属性 A 和 B(在 Id 旁边),以及几个简单的方法。
然后我有一个 Thumbnail class,它和 Image.
一模一样
在 OOP 透视图中,使 Thumbnail 继承自 Image 是合乎逻辑的。但是,在 Db 级别,这两个实体在一个重要细节上有所不同:
图片声明 FK 到另一个 table 而缩略图不是。
实际上,Image 定义了产品(例如)可以拥有的图像集(多对一),但 Thumbnail 定义了同一产品可以拥有的唯一缩略图(一对或零对-一)。在这种情况下,缩略图将不在图像集中。
因此,在数据库中,图像 table 应包含 A、B、Id 列和产品的 FK,而缩略图 table 应仅包含 A、B 和 Id 列(即也将是 FK 到产品)。
如果我使用 EF Code First 对其进行建模,充其量(我可以)它会为图像生成一个 table,然后为缩略图生成一个 table,并在图像之间生成一对一或零对一的关联和缩略图。这种关联是我试图避免的关联,因为要添加缩略图,我还必须将其添加为图像,然后设置 FK,这是不可能的,因为它有 none.
如果我明确指定生成 TPC,则它不允许我在产品和图像之间建立关联,因为关联只能在最派生的类型中定义。
你有什么想法吗?
您需要配置您的实体,以便它们使用 Mapping the Table-Per-Concrete Class (TPC) Inheritance:
In the TPC mapping scenario, all non-abstract types in the hierarchy are mapped to individual tables. The tables that map to the derived classes have no relationship to the table that maps to the base class in the database. All properties of a class, including inherited properties, are mapped to columns of the corresponding table.
这是使用 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);
在我的业务领域中,我有两个实体,作为对象,它们根据它们公开的属性定义层次关系,但在数据库级别上它们非常不同。
具体来说,我有一个图像 class,它定义了属性 A 和 B(在 Id 旁边),以及几个简单的方法。 然后我有一个 Thumbnail class,它和 Image.
一模一样在 OOP 透视图中,使 Thumbnail 继承自 Image 是合乎逻辑的。但是,在 Db 级别,这两个实体在一个重要细节上有所不同: 图片声明 FK 到另一个 table 而缩略图不是。
实际上,Image 定义了产品(例如)可以拥有的图像集(多对一),但 Thumbnail 定义了同一产品可以拥有的唯一缩略图(一对或零对-一)。在这种情况下,缩略图将不在图像集中。
因此,在数据库中,图像 table 应包含 A、B、Id 列和产品的 FK,而缩略图 table 应仅包含 A、B 和 Id 列(即也将是 FK 到产品)。
如果我使用 EF Code First 对其进行建模,充其量(我可以)它会为图像生成一个 table,然后为缩略图生成一个 table,并在图像之间生成一对一或零对一的关联和缩略图。这种关联是我试图避免的关联,因为要添加缩略图,我还必须将其添加为图像,然后设置 FK,这是不可能的,因为它有 none.
如果我明确指定生成 TPC,则它不允许我在产品和图像之间建立关联,因为关联只能在最派生的类型中定义。
你有什么想法吗?
您需要配置您的实体,以便它们使用 Mapping the Table-Per-Concrete Class (TPC) Inheritance:
In the TPC mapping scenario, all non-abstract types in the hierarchy are mapped to individual tables. The tables that map to the derived classes have no relationship to the table that maps to the base class in the database. All properties of a class, including inherited properties, are mapped to columns of the corresponding table.
这是使用 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);