实体框架为1个关系添加了3个外键

时间:2016-12-05 19:03:15

标签: c# sql-server entity-framework ef-code-first

我有一个简单的用户类

public class User
{
    public int ID { get; set; }
    [Required]
    public virtual ApplicationUser LoginID { get; set; }

    [Required]
    public string Name { get; set; }

    public string JobTitle { get; set; }

    [DefaultValue(UserRole.Standard)]
    public UserRole Role { get; set; }

    public virtual Company Company { get; set; }

    public string Email { get { return LoginID.Email; } }

    public bool HasAccess(UserRole TargetRole)
    {
     //Non-relevant logic
    }
}

我还有一个公司类定义为

public class Company
    {
        public int ID { get; set; }

        [Required]
        [MaxLength(length: 70)]
        public string Name { get; set; }

        public virtual ICollection<User> Employees { get; set; }
        public virtual ICollection<CompanyEmailDomain> Domains { get; set; }
        public ICollection<User> Managers { get { return Employees.Where(x => x.Role == UserRole.Manager).ToList(); } }
    }

但是,当我运行add-migration命令时,它会尝试将User表上的3个外键添加到Company表中。谁能告诉我为什么会这样呢?

AddColumn("dbo.Users", "Company_ID", c => c.Int());
AddColumn("dbo.Users", "Company_ID1", c => c.Int());
AddColumn("dbo.Users", "Company_ID2", c => c.Int());

1 个答案:

答案 0 :(得分:2)

实体框架只计算UserCompany之间的关联。它检测到其中三个:

    {li> Company User。 在Employees
  1. CompanyManagers
  2. Company

    他们都是1-nCompany - User),因此,EF总结说,User需要三个外键。

    知道Managers是计算属性。实际上,甚至不应该映射该属性。您应该向其添加[NotMapped]属性,或者将其映射为Fluent地图API忽略。

    此外,知道User.CompanyCompany.Employees是一个关联的两端。但由于有两个ICollection<User>属性,EF不知道为User.Company的另一端(反向结束)选择哪一个。

    现在,如果取消映射Company.Managers,EF会看到两个属性 - User.CompanyCompany.Employees - 并假设它们属于一起。因此,通过取消映射一个属性,将只创建一个外键。