实体框架代码优先,对同一实体的一对零对一和一对多关系

本文关键字:实体 一对多 关系 代码 框架 | 更新日期: 2023-09-27 18:04:49

我正在创建一个代码优先数据库与v6.0的实体框架。我有一个Organisation类和一个相关的Location类,在c#中定义如下:

public class Organisation
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Location> Locations { get; set; }
    public int? HQLocationId { get; set; }
    public Location HQLocation { get; set; }
}
public class Location
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int OrganisationId { get; set; }
    public Organisation Organisation { get; set; }
}

从类中可以推断,一个组织可以有多个位置,但是它只能有一个总部位置

我使用Fluent API来配置这些类之间的关系。"多位置"方面很简单,可以使用以下方式:

   HasMany(o => o.Locations)
      .WithRequired(o => o.Organisation)   
      .HasForeignKey(l => l.OrganisationId);

然而,我似乎找不到正确的语法来定义允许定义总部位置的关系。如果我所采用的方法存在缺陷,或者我只是缺少正确的语法?

如果我在Organisation配置中添加以下内容:

   HasOptional(o => o.HQLocation)
      .WithMany()
      .HasForeignKey(o => o.HQLocationId)
      .WillCascadeOnDelete(true);

然后实体框架不再出错,我的数据以适合我需要的形状加载。

然而,这允许位置为多个组织作为总部;这是我不希望的。

实体框架代码优先,对同一实体的一对零对一和一对多关系

一对一一对零或一关系中,Id在两个实体上应该相同。这意味着对于HQLocation, Organisation.Id必须与Location.Id相同。当然,这不是一个好的设计选择。我的建议是添加属性到Location,以表明它是否是HQLocation:

public class Organisation
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Location> Locations { get; set; }
}
public class Location
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsHqLocation { get; set; }
    public int OrganisationId { get; set; }
    public Organisation Organisation { get; set; }
}