实体框架注释,其中两个表彼此指向

时间:2013-10-18 04:19:47

标签: c# entity-framework

我正在尝试使用CodeFirst来生成我的数据库。

我有两个表StaffTeam,每个团队中有一个团队负责人是一个外部密钥,每个职员都与一个团队相关联。

public class Staff
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
    public string Username { get; set; }
    public string PasswordHash { get; set; }
    public string Salt { get; set; }
    public string Token { get; set; }
    public string Mobile { get; set; }
    public string Email { get; set; }
    public bool Admin { get; set; }
    public bool Active { get; set; }

    public int TeamID { get; set; }

    [ForeignKey("TeamID")]
    public Team Team { get; set; }
}

public class Team
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
    public int TeamLeaderID { get; set; }

    [ForeignKey("TeamLeaderID")]
    public Staff TeamLeader { get; set; }
}

因为每一个都指向另一个,我得到一个错误Unable to determine the principal end of an association between the types 'Team' and 'Staff'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.我如何以一种理解它为什么我这样做的方式对它进行注释。

2 个答案:

答案 0 :(得分:1)

以这种方式思考......首先是团队还是团队领导?如果您尝试创建团队领导者,则不能,因为您必须首先指定团队!但是如果你想创建一个团队,你就不能,因为你必须根据你的外键约束来指定团队领导者。

您必须以某种方式放松,并使其成为一个团队可以拥有一个可选的团队领导者,或者一个工作人员可以选择属于一个团队。

您可以通过将其中一个外键ID更改为可空类型来执行此操作:

public int? TeamLeaderID { get; set; }

答案 1 :(得分:0)

您的代码似乎正在尝试通过参照完整性来包含业务规则实施/责任。你的团队有一对多的关系 - >员工。您只需为TeamLeader添加一个布尔值。在进行数据库写入之前,您的逻辑应该检查您是否已经有现有的TeamLeader。

public class Staff
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
    public string Username { get; set; }
    public string PasswordHash { get; set; }
    public string Salt { get; set; }
    public string Token { get; set; }
    public string Mobile { get; set; }
    public string Email { get; set; }
    public bool Admin { get; set; }
    public bool Active { get; set; }
    public IsTeamLeader { get; set; }

}

public class Team
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }

    //virtual keyword tells Code First to create the proper Foreign Key relationship 
    public virtual List<Staff> Members{ get; set; }
}

如果你有一个庞大的系统,有很多开发人员,你可以使用流畅的API来实现你的目标,并在数据库级别强制执行你的团队领导者规则,从而防止失去联系的开发人员无意中添加第二个团队领导者任何给团队,但如果这是一个小到正常规模的项目,小团队了解公司/项目的基本知识,而不是简单的一对多关系将完成任务,你可以依靠你的业务规则/逻辑强制/保护数据库数据,以便在任何给定时间内为任何给定团队提供一个团队领导。考虑一个AddUpdateTeamMember类型方法,该方法由强制执行团队领导者要求的每个人调用。如果您仍在考虑模型第一种方法并且仍然首先尝试代码,那么存储过程是另一种轻松解决此问题的好方法。

另外考虑一下,如果在项目的某个未来某个时间点需要两个团队领导者,那么数据库可能会被“锁定”以适应这种变化。