Force inherited classes in ASP.NET Core Entity Framework Core to dedicated MySQL table

asp.net-core c# ef-code-first entity-framework-core mysql

Question

Having a model Thread that should countain all attributes of another model called Post I use inheritance:

class Post {
    public int Id{get;set;}
    public string Title{get;set;}
    // ...
}
class Thread: Post {
    public int ForumId{get;set;}
    // ...
}

EF Core put both in a single table and adds the column Discriminator. It contains the name of the class, so that .NET Core can serialize it to the correct type.

My target is:

  • Table Post with all attributes from the Post model
  • Table Thread with all attributes from models Thread and Post

Why?

  1. I'm assuming that both tables will massive grow in the future
  2. It blow up my db, since the table definition contains rows from Thread that are always empty on Post rows
  3. From a developer perspective, it simply doesn't look clean and right

What I already tried

  • Creating two different DbSet<T> in my DbContext for Post and Thread
  • Add builder.Entity<Post>().ToTable("Post") in OnModelCreating for each entity
  • Use [Table("Post")] decorator on class definition
  • Move shared attributes to a abstract chass and let Post and Thread inherit from it

Some kind of workaround

The last one works:

class Content {
    // Shared Attributes like Title
}
class Post: Content {}
class Thread: Content {}

But this cause problems when linking the entitys.

1
0
10/1/2018 10:13:46 AM

Popular Answer

What you're describing is called the TPC, or Table-Per-Concrete Type, relational pattern and is currently unsupported in Entity Framework Core. You can follow the related issue here.

There is no milestone for this feature at this time, so if you absolutely must do TPC, your only choice is to use EF6 or another alternate ORM that supports this relational strategy, instead of EF Core.

Personally, I would recommend sticking with EF Core and simply using the TPH (Table-Per-Hierarchy) or TPT (Table-Per-Type) relational strategies. The former is actually the default, and will result in a single table for both, with a Discriminator column indicating the actual type. The latter is what you get when your use the ToTable fluent config or the [Table] attribute, and results in a table for the base type holding all the shared properties, and then a table for each derived type, holding only the properties for that type, with a foreign key back to the base type's table. There's a strong relation between something like a post and a thread, and there's value in actually maintaining that relationship at the database level.

2
10/1/2018 1:10:12 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow