Search code examples
c#entity-frameworkef-code-firsttable-per-hierarchy

Entity Framework Code First TPH Discriminator Column


I'm using Entity Framework 6.0 with Code First and Table per Hierarchy (TPH) inheritance.

See the following MWE (I omit the other fluent api statements to clarify where the problem is):

public abstract class Employee 
{
   public int EmployeeId { get; set; }
   public string Type { get; set; }        
}

public class CEO : Employee
{
   public CEO() {Type = 1}
}

public class Other : Employee
{

}

public class InheritanceMappingContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<Employee>()
                .Map<CEO>(m => m.Requires("Type").HasValue(1))
                .Map<Other>(m => m.Requires("Type").HasValue(**<>1**));
    }
}

I would like to map all entries which have a 1 for the column Type (which should be the discriminator column) to the class CEO. All entries with an entry different from 1 for the column Type should be mapped to the class Other.

Two issues arise here. The first one is how to write .HasValue(**<>1**)); as correct code. The second thing is that I want to use the Type column in my code, but as this is the discriminator column I don't have access to it.


Solution

  • I don't believe it's possible to use not logic for the mapping, and I'm pretty certain it isn't possible to access the discriminator column as a property in your class.

    Also, I think conceptually there's a problem, namely, does OOP inheritance really apply to this situation? In OOP sibling classes can't be cast sideways in the inheritance hierarchy, only up and down e.g A apple can be cast to a fruit, but a apple can't be cast to an orange. In your example an employee of type "Other" may one day (with a bit of luck) become the CEO. It's a small issue and unlikely to come up and can be worked around by amending the SQL directly (ugly), but it's an indication that inheritance is not the right solution to your problem.