一对零/一关系(代码优先)

时间:2011-08-11 20:00:50

标签: entity-framework mapping entity-framework-4.1

我正在尝试这门课程:

public class Person
{
    public int PersonID { get; set; }
    public string Name { get; set; }
    public int SpouseID { get; set; }
    public virtual Person Spouse { get; set; }
}

关系是: 一个人有一个或零个配偶/ 一个配偶有一个必需的人

是否可以在Fluent API中构建此模型?

感谢。

2 个答案:

答案 0 :(得分:6)

不幸的是,由于目前EF不支持唯一密钥,因此无法进行真正的自引用一对一关系。要使这个真正的自我引用一对一SpouseID必须标记为唯一。 EF仅允许主键一对一(依赖实体中的主键必须也是主体实体的外键),这意味着自引用一对一关系将以PersonID <-> PersonID =两个实体结束单表中的PersonID。这是不可能的,因为PersonID是主键,它必须是唯一的。

您可以将其作为一对多处理,并且只显示单个导航属性,如您所知:

modelBuilder.Entity<Person>()
            .HasOptional(p => p.Spouse)
            .WithMany()
            .HasForeingKey(s => s.SpouseID);

要在数据库中强制实施一对一关系,您需要添加custom database initializer并在SpouseID列上手动创建唯一索引。

问题在于它只是单向导航,所以你可以得到人的配偶但是从那个Spouse你无法回到丈夫那里。

答案 1 :(得分:2)

这个答案是建议而不是确切的答案。

在现实世界的场景中,这不是正确的设计,首先,每个配偶都有配偶引用同一个人,例如,人的配偶配偶是人本身。我们在我们的应用程序中将其建模为Persons和PeronRelations,PersonRelations具有FromPersonID,ToPersonID和Type属性。类型指定“丈夫&lt; - &gt;妻子”,“妻子&lt; - &gt;丈夫”,“父亲&lt; - &gt;父亲”,“儿子&lt; - &gt;父亲”等。

public class Person{
   public int PersonID {get;set;}
   ...
   public ICollection<PersonRelations> FromRelations {get;set;}
   public ICollection<PersonRelations> ToRelations {get;set;}

}

public class PersonRelations{

   .. 
   public int FromPersonID {get;set;}
   public int ToPersonID {get;set;}

   public RelationType Type {get;set;} 
   public Person FromPerson {get;set;}
   public Person ToPersion {get;set;}

   // useful for Employment and Marriage 
   // durations
   public DateTime? Start {get;set;}
   public DateTime? End {get;set;}
}

public enum RelationType{
   Husband_Wife,
   Wife_Husband,
   Father_Son,
   Son_Father,
   Friend_Friend,
   Employee_Employer,
   Employer_Employee
}

这为您提供了优势,因为您可以为每个关系存储更多信息,并在两个方向上导航它们以及许多查询。

每个关系也有相应的对立关系。而且你必须编写额外的逻辑来维持正确的反向关系,以使其正常工作。

这在Entity Framework中很容易实现,因为它很简单,一对多关系。