I have seriously spent two work days trying to a TPH setup from Database First to Code first. The Error I get is Something like "Invalid Column Name Entity_EntityId/ Entity_Entity_Id1"
I've drawn up a very basic reproduction of the issue like so:
internal class Program
{
private static void Main(string[] args)
{
using (var context = new Context())
{
var baseClass = new Base {Name = "Test"};
context.BaseClasses.Add(baseClass);
context.SaveChanges();
var baseClasses = context.BaseClasses.ToList();
}
}
}
Context:
public class Context : DbContext
{
public Context() : base("TPH")
{
}
public DbSet<Base> BaseClasses { get; set; }
public DbSet<Derived> DervDerivedClasses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
Mapping:
public class BaseMap : EntityTypeConfiguration<Base>
{
public BaseMap()
{
HasKey(b => b.Id);
Property(b => b.Name);
HasOptional(b => b.AnotherClass)
.WithMany(b => b.Bases)
.HasForeignKey(b => b.AnotherClassId);
Map(b => b.Requires("Disc").HasValue(1));
}
}
public class DerivedMap : EntityTypeConfiguration<Derived>
{
public DerivedMap()
{
HasKey(b => b.Id);
Property(b => b.Name);
HasOptional(b => b.AnotherClass)
.WithMany(b => b.Deriveds)
.HasForeignKey(b => b.AnotherClassId);
Map(b => b.Requires("Disc").HasValue(2));
}
}
public class SecondDerivedMap : EntityTypeConfiguration<SecondDerived>
{
public SecondDerivedMap()
{
HasKey(b => b.Id);
Property(b => b.Name);
HasOptional(b => b.AnotherClass)
.WithMany(b => b.SecondDeriveds)
.HasForeignKey(b => b.AnotherClassId);
Map(b => b.Requires("Disc").HasValue(3));
}
}
Entities:
public class Base
{
public int Id { get; set; }
public string Name { get; set; }
public int? AnotherClassId { get; set; }
public AnotherClass AnotherClass { get; set; }
}
public class Derived : Base
{
}
public class SecondDerived : Base
{
}
public class AnotherClass
{
public int Id { get; set; }
public ICollection<Base> Bases { get; set; }
public ICollection<Derived> Deriveds { get; set; }
public ICollection<SecondDerived> SecondDeriveds { get; set; }
}
How can I get the table to just have a single "AnotherClassId?"
You're only supposed to have a single navigation property per entity per relationship -- and you have three (
Bases
,Deriveds
, andSecondDeriveds
). EF sees those properties and thinks there are three different one-to-many associations betweenAnotherClass
and the various classes in theBase
hierarchy.If you want to get a collection of the related
Derived
entities fromAnotherClass
, you're supposed to use something likeanotherClassEntity.Bases.OfType<Derived>()
.