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?

Asked on July 16, 2020 in .NET,   ASP.net.
Add Comment
1 Answer(s)

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:

  1. 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; }     } 
  1. Second option, remove Field inheritance and add its fields to Table and Column 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; }     } 
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.