I have models which inherit from each other, but I am struggling to get the fluent api configuration to behave as I want it to. Let's say I have a base class which defines some core properties
public class Entity
{
public int Id { get; set; }
public string Title { get; set };
}
And a subclass for Book
public class Book : Entity
{
public int Edition { get; set; }
}
This way I can have books, magazines, pamphlets, comics, speeches etc, all inheriting from my Entity, and not have to define the relationship on every class.
Now I add my DbSets to the DbContext like this
public class ApplicationDbContext : DbContext
{
public virtual DbSet<Book> Books { get; set; }
public virtual DbSet<Magazine> Magazines { get; set; }
public virtual DbSet<Comic> Comics { get; set; }
}
And finally I add-migration Initial.
My migration now creates separate tables (TPC) for each type. Perfect.
The problem comes when I try to configure my base class using fluent API.
I add a configuration for Entity
class EntityConfiguration : IEntityTypeConfiguration<Entity>
{
public void Configure(EntityTypeBuilder<Entity> builder)
{
builder.HasKey(e => e.Id);
builder.Property(e => e.Title).IsRequired();
}
}
The idea being that I will now only need to configure the base Entity, and all tables for the subclasses should pick up the configuration.
I add my configuration to the DbContext OnModelCreating method.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new EntityConfiguration());
}
When I add-migration, I end up with this
migrationBuilder.CreateTable(
name: "Entity",
columns: table => new
{
Edition = table.Column<int>(nullable: true),
Name = table.Column<string>(nullable: true),
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Discriminator = table.Column<string>(nullable: false),
Title = table.Column<string>(nullable: false),
Frequency = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Entity", x => x.Id);
});
By trying to configure the base class, EF is now going down the TPH route, and creating a single table for Entity with a discriminator column.
Is there a way to avoid this? Is it even possible to configure the base class and have all concrete tables pick up the configuration on the base class but create tables for the subclasses?
NOTE: I have tried configuring the Entity directly in the DbContext OnModelCreating method, instead of using a separate configuration class, but this behaves just the same.
The EF Core docs actually say TPC is not supported, which is strange because it does create separate tables for the subclasses until I try to configure the base class.
I have tried using Ignore() to suppress the TPH but this has no effect.
Example given is not real-world. My actual project has many more classes which all have common properties and relationships, so I want to avoid having to configure the same things over and over again.