【问题标题】:Can one Entity contain two different Entities of the same type, uniquely accessible?一个实体可以包含两个相同类型、唯一可访问的不同实体吗?
【发布时间】:2013-01-30 21:33:25
【问题描述】:

暂时忘记数据库和表。假设我有一个班级Spaceship 和一个班级Person。如果我正在编写Contract 模型,我可能会这样做:

public class Spaceship {
  public string LicensePlate { get; set; } //
  public string Destination { get; set; }  //Regular old data
  public Person Captain { get; set; }
  public Person Engineer { get; set; }
}

因为船长和工程师都是人,虽然他们的相关信息可能略有不同,但如果他们是同一类型,他们将保持最干燥。

但是如果我想在实体框架中建立这种关系呢?如果我在实体设计器中绘制它,我会建立这样的关系:

 ---------------------                   ---------------------
|      Spaceship      |                 |        Person       |
|---------------------|                 |---------------------|
|    LicensePlate     |                 |    Name             |
|    Destination      |                 |    PhoneNumber      |
|---------------------|                 |---------------------|
|Navigation Properties|                 |Navigation Properties|
|    People           |1---------------*|    Spaceship        |
 ---------------------                   ---------------------

但这不是一回事。因为虽然两个People 可以准确地共享同一个类,但它们与Spaceship 的关系是根本不同的。我想要一个 dbContext 我可以说

Spaceship Enterprise = new Spaceship();
Enterprise.Captain = People.Find("Kirk");
Enterprise.Engineer = People.Find("Scotty");

问的太多了吗?我的意思是,当然,还有其他方法。 Person 可以有一个 Role,即“船长”或“工程师”,然后您可以将它们全部归为 Enterprise.People。如果您经常需要访问船长,您甚至可以在 Spaceship 上创建一个 GetCaptain() 方法。

但是,为了教育,

  1. 这可能吗?
  2. 如果是这样,对实际数据库架构有什么影响?
  3. 最好的方法是什么?

【问题讨论】:

  • 有可能,您必须在 ModelBuilder 中使用 Fluent API 定义这些虚拟导航属性的映射。
  • 正如特拉维斯所说,这一切都是可能的。如果您对如何使用有疑问,我建议您使用 db first 方法。我觉得它更直观。
  • 有人愿意解释一下吗?我知道该模式如何适用于我在图中显示的标准一对多关系,但我想不出什么样的 SQL 可以实现我真正想做的事情。所以这可能是可能的,但我仍在寻找关于真正发生的事情以及这是否是好的做法的见解。

标签: sql-server asp.net-mvc database entity-framework database-design


【解决方案1】:

您可以添加 Engineer 和 Captain 表,与 Person 表具有零或一对一的关系,这将为您提供 Spaceship 的两个导航属性。如果您的模型发生更改并且任一子类型最终需要新的属性或方法,这种方法可能会很有用。

【讨论】:

  • 所以你是说Enterprise.Engineer.Person = ...?
  • 是的,但如果工程师和船长实体确实总是具有相同的属性和方法,我不确定我是否发现您在开始时提供的代码有问题。这可能会在一定程度上使事情变得更清晰,并且可以灵活应对变化。想象一下 Enterprise.Captain.Engage()
  • 我同意 - 我喜欢我开始使用的代码。但它并不能很好地转化为 SQL 设计范式。从 SQL Server 的角度来看,我不确定是否有任何警告。或任何观点。
  • 从 SQL 的角度来看,我并没有真正看到它有什么问题,尽管您可能需要根据您的计划来查看唯一值。我想这就是 OOP 如此有用的部分原因:它允许您根据软件的需要从数据模型中抽象出来。这是个好问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
  • 2013-03-03
  • 2011-02-07
  • 1970-01-01
  • 2016-04-26
  • 2015-10-20
相关资源
最近更新 更多