Search code examples
entity-framework-4ef-code-firsttable-per-type

Code First TPT Modeling where item can be multiple derived types


What is the best way to model the following kind of relationship in Code First?

abstract Person

Student: Person

Teacher: Person

Researcher: Person

...many more...

Where a person is one OR MORE derived types.

I like the idea of TPT but not sure that it is appropriate when the relationship is such that a person can be a student and a researcher.


Solution

  • You can use composition to model the scenario. This can be configured with shared primary key mapping where all the classes correspond to unique tables.

    public class Person
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    }
    
    public abstract class Role
    {
        public int PersonId { get; set; }
    
        public virtual Person Person { get; set; }
    }
    
    public class Student : Role
    {
    
    }
    
    public class Teacher : Role
    {
    
    }
    
    public class RoleContext : DbContext
    {
        public DbSet<Student> Students { get; set; }
    
        public DbSet<Teacher> Teachers { get; set; }
    
        public DbSet<Person> Persons { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>().ToTable("Student");
            modelBuilder.Entity<Student>().HasKey(s => s.PersonId);
            modelBuilder.Entity<Student>().HasRequired(s => s.Person).WithOptional();
    
            modelBuilder.Entity<Teacher>().ToTable("Teacher");
            modelBuilder.Entity<Teacher>().HasKey(t => t.PersonId);
            modelBuilder.Entity<Teacher>().HasRequired(t => t.Person).WithOptional();
        }
    }