一个人既可以是客户,也可以是顾客。
然后Client
并且Customer
不能继承自Person
. 你必须用合成来建模。不是:APerson
是一个 Client
或Customer
。相反: APerson
有一个属性是 aClient
和/或Customer
。
对于 EF,这将是两个一对一的关系:
public class Person
{
public int PersonId { get; set; }
public Client Client { get; set; }
public Customer Customer { get; set; }
}
Client
并且Customer
可以Person
参考参考Person
。(他们不需要此引用,但通过此导航属性启用对 FirstName 和 LastName 的访问是有意义的。)
public class Client / Customer
{
public int PersonId { get; set; }
public Person Person { get; set; }
}
我假设 Person 不需要总是同时具有 aClient
和Customer
属性,但有时只有一个(甚至为零?)。在这种情况下Person
is 两个关系中的主体和Client
/Customer
是从属:它们必须具有对 a 的引用Person
,但Person
唯一具有对and的可选引用。使用 Fluent API 可以这样建模:Client
Customer
modelBuilder.Entity<Person>()
.HasOptional(p => p.Client)
.WithRequired(c => c.Person);
modelBuilder.Entity<Person>()
.HasOptional(p => p.Customer)
.WithRequired(c => c.Person);
Person
和之间的关系Note
是两个普通的一对多关系。Person
可以有两个导航集合...
public ICollection<Note> NotesAsNotator { get; set; }
public ICollection<Note> NotesAsNotatee { get; set; }
...并且Note
可以有两个引用Person
以及两个外键属性(它们不需要在模型中公开,但通常很有帮助):
public int NotatorIDFK { get; set; }
public Person Notator { get; set; }
public int NotateeIDFK { get; set; }
public Person Notatee { get; set; }
并且使用 Fluent API 定义的关系如下:
modelBuilder.Entity<Person>()
.HasMany(p => p.NotesAsNotator)
.WithRequired(n => n.Notator)
.HasForeignKey(n => n.NotatorIDFK)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Person>()
.HasMany(p => p.NotesAsNotatee)
.WithRequired(n => n.Notatee)
.HasForeignKey(n => n.NotateeIDFK)
.WillCascadeOnDelete(false);
级联删除必须在此处禁用(至少对于两个关系之一),否则Person
可以Notes
通过多个级联删除路径进行删除,因为这两个关系 - 至少在 SQL Server 中 - 被禁止。
Location
andClient
和 between Location
and之间的关系又Customer
是两个一对多的关系(总共四个),其中有四个集合 inLocation
和两个对Location
inClient
和的引用Customer
。它们的建模类似于上述关系。
Client
和Email
和Customer
和之间的关系Email
是一个问题,因为它们是一对一的,但显然具有PersonIDFK
EF 不支持的外键(具有唯一键约束?)。Person
正如 Gert Arnold 在评论中已经问过的那样:为什么和之间的关系不是Email
?这两种关系是否应该表达一个人可以拥有另一个电子邮件地址作为客户而不是客户?我不明白模型的这一部分。