实体框架与同一实体的代码优先,一对零一对一和一对多关系
我正在使用Entity Framework v6.0创建代码优先的数据库.我在c#中定义了一个 Organization 类和一个相关的 Location 类,如下所示:
I'm creating a code-first database with v6.0 of the Entity Framework. I have an Organisation class and a related Location class defined in c# as follows:
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; }
}
从课程中可以推断,一个组织可以有多个位置,但是它只能有一个总部位置.
As can be inferred from the classes, an Organisation can have multiple Locations, however it can only have one Head Quarters Location.
我正在使用Fluent API来配置这些类之间的关系. 多个位置"方面非常简单,可用于以下方面:
I'm using the Fluent API to configure the relationships between these classes. The "multiple locations" aspect is simple enough and works with the following:
HasMany(o => o.Locations)
.WithRequired(o => o.Organisation)
.HasForeignKey(l => l.OrganisationId);
但是,我似乎找不到正确的语法来定义允许定义总部位置的关系.如果我采用的方法存在缺陷,还是我只是缺少正确的语法?
I cannot however seem to find the correct syntax to define the relationship that allows the HQ location to be defined. If there a flaw in the approach I'm taking, or am I simply missing the right syntax?
更新
如果我在组织配置中添加以下内容:
If I add the following to the Organisation configuration:
HasOptional(o => o.HQLocation)
.WithMany()
.HasForeignKey(o => o.HQLocationId)
.WillCascadeOnDelete(true);
然后实体框架不再出错,并且我的数据以适合我需要的形状加载.
Then Entity Framework no longer errors and my data loads in a shape that suits my needs.
但是,这允许将位置用作多个组织的总部;理想情况下,我不希望这样做.
However this allows a Location to be the HQ for more than one Organisation; which ideally I do not want possible.
在一对一或一对零或一个关系中Id
在两个实体上都相同.这意味着Organisation.Id
必须与HQLocation
的Location.Id
相同.当然,这不是一个好的设计选择.我建议向Location
添加属性以指示它是否为HQLocation
:
In one-to-one or one-to-zero or one relationships Id
should be same on both entities. This means that Organisation.Id
must be same as Location.Id
for HQLocation
. And of course, it is not good design choice. What I recommend is to add property to Location
to indicate whether it is a HQLocation
or not:
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; }
}