2015-12-06 67 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);