EntityFramework composite foreign key with inheratince
I have an Entity Framework project, which has such models and configurations.
public class Context : DbContext { public DbSet<Field> Fields { get; set; } public DbSet<Table> Tables { get; set; } public DbSet<Column> Columns { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Configurations.Add(new FieldConfiguration()); modelBuilder.Configurations.Add(new TableConfiguration()); modelBuilder.Configurations.Add(new ColumnConfiguration()); } } public class Field { public Guid Guid { get; set; } public Guid CompanyGuid { get; set; } } public class Column : Field { public Guid TableGuid { get; set; } public Table Table { get; set; } } public class Table : Field { public List<Column> Columns { get; set; } } public class FieldConfiguration : EntityTypeConfiguration<Field> { public FieldConfiguration() { Map(t => { t.ToTable("Field"); }); HasKey(p => new { p.Guid, p.CompanyGuid }); Property(p => p.Guid).HasColumnName("Guid").IsRequired(); Property(p => p.CompanyGuid).HasColumnName("CompanyGuid").IsRequired(); } } public class ColumnConfiguration : EntityTypeConfiguration<Column> { public ColumnConfiguration() { Map(t => { t.ToTable("Column"); }); HasKey(p => new { p.Guid, p.CompanyGuid }); Property(p => p.Guid).HasColumnName("Guid").IsRequired(); Property(p => p.CompanyGuid).HasColumnName("CompanyGuid").IsRequired(); } } public class TableConfiguration : EntityTypeConfiguration<Table> { public TableConfiguration() { Map(t => { t.ToTable("Table"); }); HasKey(p => new { p.Guid, p.CompanyGuid }); Property(p => p.Guid).HasColumnName("Guid").IsRequired(); Property(p => p.CompanyGuid).HasColumnName("CompanyGuid").IsRequired(); HasMany(t => t.Columns).WithRequired(t => t.Table).HasForeignKey(t => new { t.TableGuid, t.CompanyGuid }).WillCascadeOnDelete(true); } }
Then I try to create a Migration, and I get such error
The foreign key component ‘CompanyGuid’ is not a declared property on type ‘Column’. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.
What’s wrong? And how do I fix it?
Here the source of the problem is Field
entity. It is used as a Database Table and at the same time used as a base class for the other table entities. EF doesn’t let the property, that is used on the foreign key constraint, to be on multiple tables with inheritance, like in this case CompanyGuid
property is a column of both Field
and its derived Column
entities.
To overcome this EF restriction I can propose two solutions for you:
- First option, create a completely separate base class and derive all your 3 entities from that base class:
public abstract class EntityBase { public Guid Guid { get; set; } public Guid CompanyGuid { get; set; } } public class Field : EntityBase { } public class Column : EntityBase { public Guid TableGuid { get; set; } public Table Table { get; set; } } public class Table : EntityBase { public List<Column> Columns { get; set; } }
- Second option, remove
Field
inheritance and add its fields toTable
andColumn
entities explicitly as below:
public class Field { public Guid Guid { get; set; } public Guid CompanyGuid { get; set; } } public class Column { public Guid Guid { get; set; } public Guid CompanyGuid { get; set; } public Guid TableGuid { get; set; } public Table Table { get; set; } } public class Table { public Guid Guid { get; set; } public Guid CompanyGuid { get; set; } public List<Column> Columns { get; set; } }