Listen to this Post

When working with Entity Framework Core (EF Core), the Discriminator column is a powerful feature for implementing Table per Hierarchy (TPH) inheritance. This approach allows storing different derived entities (e.g., Car, Bike) in a single database table while distinguishing them using a discriminator value.
Key Concepts
- Shared Properties: Base class properties (e.g.,
Id,Model) are stored in a single table. - Unique Properties: Subclass-specific properties (e.g., `NumberOfDoors` for
Car, `HasGear` forBike) are stored in the same table. - Automatic Instantiation: EF Core uses the discriminator to instantiate the correct object type when querying.
Implementation Steps
1. Define Base and Derived Classes
public class Vehicle
{
public int Id { get; set; }
public string Model { get; set; }
}
public class Car : Vehicle
{
public int NumberOfDoors { get; set; }
}
public class Bike : Vehicle
{
public bool HasGear { get; set; }
}
2. Configure TPH in DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Vehicle>()
.HasDiscriminator<string>("VehicleType")
.HasValue<Car>("Car")
.HasValue<Bike>("Bike");
}
3. Querying Polymorphically
var vehicles = context.Vehicles.ToList();
foreach (var vehicle in vehicles)
{
if (vehicle is Car car)
Console.WriteLine($"Car with {car.NumberOfDoors} doors");
else if (vehicle is Bike bike)
Console.WriteLine($"Bike with gear: {bike.HasGear}");
}
4. Inserting Records
context.Vehicles.Add(new Car { Model = "Tesla", NumberOfDoors = 4 });
context.Vehicles.Add(new Bike { Model = "BMX", HasGear = true });
context.SaveChanges();
You Should Know: Advanced EF Core Commands & Practices
1. Changing the Discriminator Column Name
By default, EF Core uses `Discriminator`. To customize:
modelBuilder.Entity<Vehicle>()
.HasDiscriminator<string>("VehicleType");
2. Raw SQL for Performance Optimization
var cars = context.Vehicles
.FromSqlRaw("SELECT FROM Vehicles WHERE VehicleType = 'Car'")
.ToList();
3. Handling Complex Inheritance
For multiple levels:
modelBuilder.Entity<Vehicle>()
.HasDiscriminator<string>("VehicleCategory")
.HasValue<ElectricCar>("ElectricCar")
.HasValue<SportsCar>("SportsCar");
4. Indexing the Discriminator for Faster Queries
modelBuilder.Entity<Vehicle>() .HasIndex(v => EF.Property<string>(v, "VehicleType"));
5. Using Discriminator in LINQ
var bikes = context.Vehicles .Where(v => EF.Property<string>(v, "VehicleType") == "Bike") .ToList();
6. Migration Commands
dotnet ef migrations add AddVehicleHierarchy dotnet ef database update
7. Querying Without Loading All Types
var carsOnly = context.Vehicles.OfType<Car>().ToList();
What Undercode Say
The Discriminator column in EF Core simplifies polymorphic data storage while maintaining performance. Key takeaways:
✔ Single-table efficiency – Reduces JOIN operations.
✔ Automatic type resolution – EF Core handles instantiation.
✔ Flexible querying – Supports LINQ, raw SQL, and filtering.
For large-scale apps, consider:
- Indexing discriminators for faster queries.
- Using TPC (Table per Concrete Class) if subclass properties vary significantly.
Expected Output
A structured EF Core implementation with optimized queries, migrations, and polymorphic data handling.
🔗 Learn More: EF Core Inheritance Strategies
References:
Reported By: Djokic Stefan – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


