Entity Framework Core 5 — Table-per-Type and Table-per-Hierarchy



A new feature that was added on Entity Framework Core 5, it’s the possibility to create a Table-per-Type (TPT) mapping. In this article, I explain the difference between the Table-per-Hierarchy (TPH) mapping and the Table-per-Type (TPT) mapping.


By default, EF Core maps an inheritance hierarchy of .NET types to a single table in the database, to store the data for all types in the hierarchy, and a discriminator column is used to identify which type each row represents, this is known as Table-per-Hierarchy (TPH) mapping.


With EF Core 5, it’s also possible to map each .NET type in an inheritance hierarchy to a different table, and this is known as Table-per-Type (TPT) mapping. With this new functionality, EF Core creates a base table in the database and create a specific table for each derived table.


To show the differences between the TPH and the TPT mapping, I’ve created a console application using .NET Core 5.0, and I’ve installed the packages:

  • Microsoft.EntityFrameworkCore.Design 5.0.3

  • Microsoft.EntityFrameworkCore.SqlServer 5.0.3

  • Microsoft.EntityFrameworkCore.Tools 5.0.3


On the Startup class, in the method OnConfiguring, I enabled the option to Log into the console all the queries generated by EF Core:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    const string strConnection ="Data source=(localdb)\\mssqllocaldb; 
    Initial Catalog=EntityFrameworkCore5Examples;
    Integrated Security=true;
    pooling=true;";
    optionsBuilder        
        .UseSqlServer(strConnection)        
        .EnableSensitiveDataLogging()        
        .LogTo(Console.WriteLine, LogLevel.Information);
}


Table-per-Hierarchy (TPH) Mapping


For demonstration purpose, I’ve created three entities, and I will use them to explain the Table-per-Hierarchy (TPH) mapping and the Table-per-Type (TPT) mapping. These are the classes: