【问题标题】:Entity Framework - Code first - Data annotations - Unnecessary foreign key columns实体框架 - 代码优先 - 数据注释 - 不必要的外键列
【发布时间】:2016-03-07 08:29:59
【问题描述】:

Entity Framework 正在我的 AccountCompanyRole 表中创建两个不必要的列。

AccountCompany

public class AccountCompany
{
    [Key, Column(Order = 0), ForeignKey("Account")]
    public int AccountID { get; set; }

    [Key, Column(Order = 1), ForeignKey("Company")]
    public int CompanyID { get; set; }

    public virtual Account Account { get; set; }

    public virtual Company Company { get; set; }

    public virtual ICollection<AccountCompanyRole> AccountCompanyRoles { get; set; }
}

AccountCompanyRoles

public class AccountCompanyRole
{
    [Key, Column(Order = 0), ForeignKey("AccountCompany")]
    public int AccountID { get; set; }

    [Key, Column(Order = 1), ForeignKey("AccountCompany")]
    public int CompanyID { get; set; }

    [Key, Column(Order = 2), ForeignKey("Role")]
    public int RoleID { get; set; }

    public virtual AccountCompany AccountCompany { get; set; }

    public virtual Role Role { get; set; }
}

OnModelCreating

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AccountCompanyRole>()
            .HasRequired(p => p.AccountCompany)
            .WithMany()
            .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }

数据库中的结果

如您所见,EF 在 AccountCompanyRoles 中添加了两个额外的外键,即使我在 Data Annotations 中指定了主键和外键。

问题

  1. 如何防止它创建 AccountCompany_AccountID 和 AccountCompany_CompanyID?

  2. 这是我所追求的最佳结构吗?我应该改用一个主键并将 IsUnique 索引放在 AccountID 和 CompanyID 上吗?这可能会解决我的问题..

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework entity-framework-6


    【解决方案1】:

    如何防止它创建 AccountCompany_AccountID 和 AccountCompany_CompanyID?

    首先,从CompanyID 和RoleID 中删除ForeignKey 属性。

    然后将ForeignKey 属性放在您的AccountCompany 成员上,如下所示:

    public class AccountCompanyRole
    {
        [Key, Column(Order = 0)]
        public int AccountID { get; set; }
    
        [Key, Column(Order = 1)]
        public int CompanyID { get; set; }
    
        [Key, Column(Order = 2), ForeignKey("Role")]
        public int RoleID { get; set; }
    
        [ForeignKey("AccountID, CompanyID")]
        public virtual AccountCompany AccountCompany { get; set; }
    
        public virtual Role Role { get; set; }
    }
    

    或者像这样使用流畅的配置:

    modelBuilder.Entity<AccountCompanyRole>()
                .HasRequired(r => r.AccountCompany)
                .WithMany(c => c.AccountCompanyRoles)
                .HasForeignKey(r => new { r.AccountID, r.CompanyID })
                .WillCascadeOnDelete(false);
    

    这是我所追求的最佳结构吗?我应该改用一个主键并将 IsUnique 索引放在 AccountID 和 CompanyID 上吗?这可能会解决我的问题..

    IMO 都是有效的方法,请使用更适合您需求的方法。

    【讨论】:

    • 嗨!我使用 Data Annoitations 和 Fluent API 尝试了您的建议,但我的 AccountCompanyRole 表中仍然有两个额外的列。我什至删除了数据库/迁移并重新创建了我的数据库,但这也无济于事..
    • 还必须为 AccountCompany 添加流畅的配置。但是,我赞成您提供如此详细的答案。谢谢
    • @Reft 欢迎您。很高兴您的问题已经解决。然而,“解决方案”的气味。配置一个相同的关系两次是没有意义的。我已经在我的 EF 环境中检查过了,问题是 WithMany() 调用,应该和更新后的答案一样。
    【解决方案2】:

    您必须像这样在流畅的关系中指定外键:

    modelBuilder.Entity<AccountCompanyRole>()
                .HasRequired(p => p.AccountCompany)
                .WithMany().HasForeignKey(d => new { d.AccountID, d.CompanyID })
                .WillCascadeOnDelete(false);
    
            modelBuilder.Entity<AccountCompany>()
                .HasMany(c => c.AccountCompanyRoles)
                .WithRequired(d => d.AccountCompany)
                .HasForeignKey(e => new {e.AccountID, e.CompanyID});
    

    编辑: 为 AccountCompany 添加了流利的配置

    【讨论】:

    • 我的 AccountCompanyRole 表中仍然有两个额外的列。我什至删除了 DB/Migrations 并重新创建了我的 DB,但这也无济于事。
    • 尝试为您的 AccountCompany 关系添加流利的配置(查看更新的答案)
    • 谢谢 :)
    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 2013-03-07
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 2021-01-05
    相关资源
    最近更新 更多