繁体   English   中英

具有继承性的 EntityFramework 复合外键

[英]EntityFramework composite foreign key with inheratince

我有一个实体框架项目,它有这样的模型和配置。

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);
    }
}

然后我尝试创建一个迁移,我得到这样的错误

外键组件“CompanyGuid”不是“列”类型的声明属性。 验证它没有被明确地从 model 中排除,并且它是一个有效的原始属性。

怎么了? 我该如何解决?

这里问题的根源是Field实体。 它用作数据库表,同时用作其他表实体的基础 class。 EF 不允许用于外键约束的属性位于具有 inheritance 的多个表上,例如在本例中, CompanyGuid属性是Field及其派生Column实体的列。

为了克服这个 EF 限制,我可以为您提出两种解决方案:

  1. 第一个选项,创建一个完全独立的基础 class 并从该基础 class 派生所有 3 个实体:
    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. 第二个选项,删除Field inheritance 并将其字段显式添加到TableColumn实体,如下所示:
    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; }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM