0

数据结构

这是一个相对简单的数据结构,但我很难找出最佳的 EF 策略来对其进行建模。这显然不是 Table Per Hierarchy。所以我尝试了每个类型的表,它不喜欢客户和个人或客户和个人之间的关系。在阅读了每个具体类型的表之后,它也不遵循该模型。S 如何为这个 ERD 建模?

#

更新

#

它背后的业务用例是我们与几家公司打交道。其中一些公司收购了其他公司。母公司 (Acme) 是长期客户。子公司(Zeta)是长期客户。当 Acme 收购 Zeta 时,他们指定了一名负责处理公司之间关系的人(Adam)。Adam 现在有 2 个不同的电子邮件地址需要收到事件通知。adam@acme.com 接收客户通知。adam@zeta.com 获取客户端通知。这就是我让它像原来那样建模的原因。Adam 有点强迫症,喜欢将他的通知分开到单独的邮箱中。作为一个程序员,我不喜欢 Adam。:D

除了客户和客户之外,系统中还有其他几个分类。我们还有供应商、技术人员和分销商。我最终将它建模为与以下建议非常相似,但将电子邮件表拆分为特定类型的表(CustomerEmail 和 ClientEmail)。不完美,但为了“完成它”,它可以工作。

4

1 回答 1

3

一个人既可以是客户,也可以是顾客。

然后Client并且Customer不能继承自Person. 你必须用合成来建模。不是:APerson 是一个 ClientCustomer相反: 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 不需要总是同时具有 aClientCustomer属性,但有时只有一个(甚至为零?)。在这种情况下Personis 两个关系中的主体和Client/Customer是从属:它们必须具有对 a 的引用Person,但Person唯一具有对and的可选引用。使用 Fluent API 可以这样建模:ClientCustomer

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 中 - 被禁止。

LocationandClient和 between Locationand之间的关系又Customer是两个一对多的关系(总共四个),其中有四个集合 inLocation和两个对LocationinClient和的引用Customer。它们的建模类似于上述关系。

ClientEmailCustomer和之间的关系Email是一个问题,因为它们是一对一的,但显然具有PersonIDFKEF 不支持的外键(具有唯一键约束?)。Person正如 Gert Arnold 在评论中已经问过的那样:为什么和之间的关系不是Email?这两种关系是否应该表达一个人可以拥有另一个电子邮件地址作为客户而不是客户?我不明白模型的这一部分。

于 2013-02-07T21:14:23.763 回答