I have a model where most of the entities inherit the same base functionality. That functionality is encapsulated in an abstract base class. Above that, there are two branches of functionality and thus there are two abstract classes that inherit from the abstract base class. At this point, concrete classes inherit from their respective intermediate abstract classes.
Below is an example of the classes and EF mapping for one branch of this type of model model:
public class TestContext : DbContext
{
public DbSet<Base> Bases { get; set; }
public DbSet<Intermediate> Intermediates { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Intermediate>().ToTable("Concretes");
modelBuilder.Entity<Concrete1>().ToTable("Concretes");
modelBuilder.Entity<Concrete2>().ToTable("Concretes");
}
}
public abstract class Base
{
public int Id { get; set; }
public string BaseString { get; set; }
public int BaseInteger { get; set; }
}
public abstract class Intermediate : Base
{
public string IntermediateString { get; set; }
public int IntermediateInteger { get; set; }
}
public class Concrete1 : Intermediate
{
public string Concrete1String { get; set; }
public int Concrete1Integer { get; set; }
}
public class Concrete2 : Intermediate
{
public string Concrete2String { get; set; }
public int Concrete2Integer { get; set; }
}
Where I am running into issues is with the table mapping. While mapping Intermediate
, Concrete1
, and Concrete2
does generate a database- and even gives me a discriminator column- it does not make the columns nullable as is required for TPH mapping and therefore I end up with the following exception message:
(28,10) : error 3023: Problem in mapping fragments starting at line 28:Column Concretes.Concrete1Integer in table Concretes must be mapped: It has no default value and is not nullable.
I've tried several permutations of this-
Intermediate
to a custom table- works, but the concrete types' fields are mapped to the "Bases" table.Intermediate
to its own table and Concrete1
& Concrete2
to a table named "Concretes"- Exact same issues as the original mapping in the code example above.Is there not some way to get the mapping I'm looking for in the code example? That is, a "Bases" table and a "Concretes" table that uses a discriminator?
As of version Entity Framework 6.1.0, this is an outstanding bug. It sounds like it will be a bug in 6.1.1 as well, but a fix has been scheduled for 6.1.2.