EF Core implementing Table-Per-Concrete-Type with fluent mapping of abstract base class

c# entity-framework-core

Question

Suppose that you have two entities derived from an abstract base class and you want implement Table-Per-Concrete-Type. Entities like below:

public abstract class EntityBase
{
   public int Id { get; set; }

   public string CreatedBy { get; set; }

   public DateTime CreatedAt { get; set; }
}

public class Person : EntityBase
{
   public string Name { get; set; }
}
public class PersonStatus : EntityBase
{
   public string Title { get; set; }
}

And you don’t want to use attribute in the abstract base class(EntityBase), you want to map EntityBase class in dbcontext only once for all entities. How to change the code below :

public class PeopleDbContext : DbContext
{
   public DbSet<Person> People { get; set; }

   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
      base.OnModelCreating(modelBuilder);

      // Entity base class mapping(only once)

      modelBuilder.Entity<Person>(e =>
      {
        e.Property(x => x.Name)
            .IsRequired()
            .HasMaxLength(100);
      });
      modelBuilder.Entity<PersonStatus>(e =>
      {
        e.Property(x => x.Title)
            .IsRequired()
            .HasMaxLength(100);
      });
  }

}
1
4
4/1/2016 11:19:57 AM

Popular Answer

Here is an answer to your question..

You need to write Configurations for your BaseClass:

public class EntityBaseConfiguration<TBase> : IEntityTypeConfiguration<TBase>
    where TBase : EntityBase
{
    public virtual void Configure(EntityTypeBuilder<TBase> builder)
    {
        builder.HasKey(b => b.Id);
        builder.Property(b => b.CreatedBy)
            .HasColumnType("varchar(50)");
        builder.Property(b => b.CreatedAt)
            .HasColumnType("datetime2");
    }
}

After that, you can write your concrete Configuration-Class foreach Table which inherits from EntityBase like so:

public class PersonConfig : BaseConfig<Person>
{
    public override void Configure(EntityTypeBuilder<Person> builder)
    {
        base.Configure(builder);
        builder.Property(e => e.Name)
            .HasColumnType("varchar(100)")
            .IsRequired();
    }
}

To invoke your configuration in your dbContext you can call ApplyConfiguration:

public class PeopleDbContext : DbContext
{
    public DbSet<Person> People { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new PersonConfig());
    }
}
3
8/30/2017 10:59:24 AM


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