Advertisement
Поиск  
Always will be ready notify the world about expectations as easy as possible: job change page
Mar 1, 2023

Inheritance strategies in Entity Framework Core 7

Автор:
Alper Ebiçoğlu
Источник:
Просмотров:
1773

In this article, I’ll show you all the object mapping strategies of EF Core and especially the new one: TPC Inheritance Mapping. TPC mapping is the new feature introduced with Entity Framework Core 7. It’s called Table Per Concrete type inheritance mapping. I’ll explain the EF Core’s inheritance mapping strategies with how the inherited entity and the specific information are saved into a relational database. I’ll also explain which strategy is best for your case.

By default, EF Core maps an inheritance hierarchy of .NET types to a single database table. And it’s called TPH (table-per-hierarchy) mapping.

In the previous versions EF Core , Table Per Hierarchy (TPH) or Table Per Type (TPT) were supported. And now TPC came!

To explain in a more clear way, I’ll use the following entity model. Car, Bus and Motorcylce are inherited from the Vehicle object.

public abstract class Vehicle
{
    public int Id { get; set; }
    public string VehicleModel { get; set; }
}

//////////////////////////////////////

public class Car : Vehicle
{
    public string Segment { get; set; }
}

//////////////////////////////////////

public class Bus : Vehicle
{
    public int? SeatCount { get; set; }
}

//////////////////////////////////////

public class Motorcycle : Vehicle
{
    public int CylinderCount { get; set; }
}

Here’s the list of available strategies to map Car, Bus and Motorcycle.

TPH (Table Per Hierarchy)

TPH maps an inheritance hierarchy of .NET types to a single database table. So a single table is created for all types. This is the default behavior of EF Core. If you explicitly want to use this strategy, you can write UseTphMappingStrategy() to the root entity in the OnModelCreating() method in the DbContext class. As you see from the following table, it adds an extra column, Discriminator to separate the Car, Bus and Motorcycle. This way of persistence is an unnormalized form.

CREATE TABLE [Vehicles] (
    [Id] int NOT NULL IDENTITY,   
    [Discriminator] nvarchar(max) NOT NULL,  -- "Car", "Bus", "Motorcylce"
    [VehicleModel] nvarchar(max) NOT NULL,
    [Segment] nvarchar(max) NULL,
    [SeatCount] int NULL,
    [CylinderCount] int NOT NULL
);

TPT (Table per Type)

With the TPT strategy, a different table is created for every type. The table itself is used to determine the type of the object saved, and each table contains only columns for the properties of that type. The data is saved in multiple tables, and this way of persistence is normalized form.

CREATE TABLE [Vehicles] (
    [Id] int NOT NULL IDENTITY,
    [VehicleModel] nvarchar(max) NOT NULL
);

CREATE TABLE [Car] (
    [Id] int NOT NULL,
    [Segment] nvarchar(max) NULL
);

CREATE TABLE [Bus] (
    [Id] int NOT NULL,
    [SeatCount] int NULL,
);

CREATE TABLE [Motorcycle] (
    [Id] int NOT NULL,
    [CylinderCount] int NOT NULL
);

If you explicitly want to use this strategy, you can write UseTptMappingStrategy() to the root entity in the OnModelCreating() method in the DbContext class.

TPC (Table Per Concrete type)

It’s the new strategy that has been introduced with EF Core 7. In this way, a different table is created for each concrete type. While in the TPT, the table itself indicates the type of the object saved, in TPC, each table contains columns for every property in the concrete type and its base types. As you see from the following tables, no Vehicles table is being created. The VehicleModel field is common in each table.

CREATE TABLE [Car] (
    [Id] int NOT NULL DEFAULT (NEXT VALUE FOR [VehicleIds]),
    [VehicleModel] nvarchar(max) NOT NULL, -- common field for each type
    [Segment] nvarchar(max) NULL
);

CREATE TABLE [Bus] (
    [Id] int NOT NULL DEFAULT (NEXT VALUE FOR [VehicleIds]),
    [VehicleModel] nvarchar(max) NOT NULL, -- common field for each type
    [SeatCount] int NULL
);

CREATE TABLE [Motorcycle] (
    [Id] int NOT NULL DEFAULT (NEXT VALUE FOR [VehicleIds]),
    [VehicleModel] nvarchar(max) NOT NULL, -- common field for each type
    [CylinderCount] int NOT NULL
);

This strategy maps each .NET type to a different database table. You write UseTpcMappingStrategy() to the root entity in the root entity in the OnModelCreating() method in the DbContext class.

How do you choose which mapping type is best for you?

  • TPH: In most cases, the TPH mapping is a good choice which is the default one. This way, the table columns increase because all the properties are saved in the same table, but it’s easy to query in a single table.
  • TPT In this form, data is persisted in a normalized form. For this reason, you can choose TPT, but generally, it’s not being used. But the disadvantage is when you filter by VehicleModel column, it must join Vehicles, Bus, Car, Motorcycle tables. So it's not a feasible fetching way.
  • TPC: This new strategy is similar to TPT but resolves some of the TPT problems. Because it stores the data in its own table, it doesn’t divide across multiple tables. This option can be chosen when the mapped hierarchy is large and has many concrete types, each with many properties.

For example, if Car, Bus, or Motorcycle have 20 properties for each type, then it's better to store them in a separate table, so we should use TPC. But if these entities have only 3-5 properties, then TPH is the way to go.

Похожее
Apr 6, 2013
IntroductionA dynamic SQL in a stored procedure is a single Transact-SQL statement or a set of statements stored in a variable and executed using a SQL command. There may be several methods of implementing this in SQL Server. This article...
Nov 20, 2022
Author: Juldhais Hengkyawan
Sometimes we have to perform several queries to the database, put the results into memory, and then process them as needed.For example, we have a Supplier table and a Customer table. Both tables have a substantial amount of data. We...
Oct 26, 2023
Author: Alex Maher
Entity Framework Core Features in 2023EF Core 2023 has rolled out some pretty cool stuff, and I’m excited to share it with you. So, grab a cup of coffee, and let’s get started!1. Cosmos DB Provider ImprovementsAzure Cosmos DB and...
Jun 15, 2021
Author: Emre Kizildas
Hi everyone, this article include encrypting your database columns with EntityFramework. Your database providers can be MSSQL or PostgreSQL.Considering that some database columns contain confidential data, it is of great importance that the data is encrypted in case of capture...
Написать сообщение
Почта
Имя
*Сообщение


© 1999–2024 WebDynamics
1980–... Sergey Drozdov
Area of interests: .NET Framework | .NET Core | C# | ASP.NET | Windows Forms | WPF | HTML5 | CSS3 | jQuery | AJAX | Angular | React | MS SQL Server | Transact-SQL | ADO.NET | Entity Framework | IIS | OOP | OOA | OOD | WCF | WPF | MSMQ | MVC | MVP | MVVM | Design Patterns | Enterprise Architecture | Scrum | Kanban