entity-frameworkef-code-firstentity-framework-6tph

TPH Discriminator not on base class / table


I'm having an issue with discriminators in TPH inheritance with Entity Framework v6.1.1

I would expect that the discriminator should fall on the table that is representative of the base class. However, it appears EF is trying to map the discriminator column to the table mapped to the derived class

E.g.

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Staff : Person
{
    public decimal? Salary { get; set; }
}

public class MyContext : DbContext
{
    public MyContext()
        : base("MyConnectionString") {}

    public virtual IDbSet<Person> Persons { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .Map(x => x.ToTable("Person"))
            .Map<Staff>(x => x.ToTable("Staff").Requires("PersonTypeId").HasValue(1));
    }
}

I am also using an existing schema too - i.e:

CREATE TABLE Person
(
    Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Name VARCHAR(50) NULL,
    PersonTypeId INT NOT NULL
)

CREATE TABLE Staff 
(
    Id INT NOT NULL REFERENCES Person(Id),
    Salary DECIMAL NULL
)
GO

However, when I try to add a new Staff, I encounter the following exception:

'System.Data.SqlClient.SqlException : Cannot insert the value NULL into column 'PersonTypeId', table 'MyDb.dbo.Person'; column does not allow nulls. INSERT fails. The statement has been terminated'

It appears that it is trying to insert the discriminator (incorrectly) to the derived table. Hope someone can help.


Solution

  • So it appears that I've mis-understood the TPH setup for Entity Framework.

    In my case, I'm wanting to map derived types to separate tables, which is an example of Table per Type - http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt

    Discriminators are redundant in this context.