简体   繁体   中英

Entity Framework - How to avoid TPC in a class hierarchy

In my business domain I have two entities which, as objects, defines a hierarchical relationship according to the properties they expose but that at the Data Base level they are very different.

Specifically, what I have is an Image class, which defines the properties A and B (beside the Id), and several simple methods. Then I have a Thumbnail class, which is exactly the same than Image.

Inside an OOP perspective, it is logical to make Thumbnail inherit from Image. But, at the Db level these two entities differ in one important detail: Image declare a FK to another table and Thumbnail not.

Actually, Image defines the set of image that a Product (for example) can have (Many-to-One) but Thumbnail defines the only thumbnail that the same Product can have (One-or-Zero-to-One). In this case, the Thumbnail wouldn't be in the Image set.

So, at the DB, the Image table should have columns A, B, Id and the FK to Product while the Thumbnail table should only have columns A, B and Id (that also will be the FK to Product).

If I model this using EF Code First, at best (as I could) it generates a table for Image and then one for Thumbnail and a One-or-Zero-to-One association between Image and Thumbnail. This association is the one that I'm trying to avoid, because for adding a Thumbnail I have to also add it as an image and then setting the FK, which is impossible because it have none.

If I explicitly specify to generate a TPC then it doesn't allows me to establish an association between Product an Image because associations shall be defined only in the most derived types.

Do you have any ideas?

You need to configure your entities, so that they use 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.

This is a sample of a possible configuration using TPC::

modelBuilder.Entity<Image>() 
  .Property(c => c.ImageID) 
  .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

modelBuilder.Entity<ThumbNail>().Map(m => 
{ 
    m.MapInheritedProperties(); 
    m.ToTable("Thumbnails");
}); 

You'll have to fine tune it for your particular purposes. For example, excluding the FK property with:

modelBuilder.Entity<Thumbnail>().Ignore(p => p.FkProperty);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM