【问题标题】:In DDD, how to create/edit domain ValueObjects ASP.NET MVC?在 DDD 中,如何创建/编辑域 ValueObjects ASP.NET MVC?
【发布时间】:2015-04-15 12:19:20
【问题描述】:

我们已将数据库中的 Location 实体标识为我们域 (DDD) 中的值对象。位置被其他域对象使用,但并不真正“独立”——它们总是属于另一个实体。

现在我们尝试在一个简单的 MVC Web 应用程序中编辑这些值的列表。因此视图将在视图模型LocationViewModel 中显示位置列表。

但是,根据定义,值对象是不可变,但确实包含对另一个实体的引用 (Business)。

域:

public class Location : ValueObject<Location>
{
  readonly locationId;

  public int LocationId {get{return _locationId;}}
  public Business Business {get;set;}
}

我的问题是了解如何在 UI 中简单地编辑一堆值对象并进行更改,例如该位置属于什么业务。 值对象不应该具有“身份”,但它确实需要一个 ID,以便存储库可以更新数据库。

我也不认为你可以仅仅因为你想在 UI 中编辑它就将 Location 设为一个实体。还是Location,在这种情况下确实是一个实体? 我不明白什么?

谢谢!

【问题讨论】:

  • 您域中的位置是什么?它是如何使用的?它是如何共享的?如果共享位置值发生更改,是否应将更改反映在绑定到同一位置的实体中?
  • 位置是您存储和放置物品的地方,例如架子或展示柜。您可以将项目分配到位置。因此,如果将项目分配给某个位置,则您无法删除该位置。位置还与企业和实际地址相关联。我不相信一个位置是“共享的”,它有自己的一组与其他表相关的表,例如业务,项目。
  • 如果您一直试图关注持久性问题,您将永远无法理解 DDD。忘记数据库表或任何其他持久性细节。想想Location 是如何被您域中的其他对象使用的。是什么让您认为 Location 是一个值对象?

标签: asp.net-mvc c#-4.0 domain-driven-design value-objects


【解决方案1】:

这是一个经典问题。在一种情况下,它是一个实体,而在另一种情况下,它是一个值对象。我发现电话号码的例子有助于理解这类问题。

例如,在 CRM 中,电话号码是一个值对象。同一个联系人可以关联多个联系人。它因价值而异(这里的关键概念)。所以在这种情况下,它是一个值对象。在这个例子中,我可以将电话号码存储在数据库中,而“ID”就是电话号码本身。如果值对象由多个部分组成,那么它们将形成一个复合键。

但是,如果我们查看电话公司的电话号码。那很可能是一个实体。它可以附有所有庄园的信息。所有这些信息都会因 ID(在本例中为数字)而异。

在您的情况下, Location 听起来像一个值对象。如果您需要将它作为一个事物而不是作为实体的一部分保存在数据库中,那么将它的部分用作复合键。您将需要处理“更改”时发生的事情,因为这不是更改而是创建新的值对象。一种方法是删除旧的并插入新的。或者只保留所有版本。这取决于您的域。

希望对您有所帮助。

【讨论】:

  • @Codescibler 谢谢先生!因此,如果我正确理解这一点,是否允许单独编辑值对象?为此,我确实需要将其视为具有 ID 字段,以便我可以“查找”/更新/删除数据库中更改的记录?当链接到另一个实体时,它的不变性意味着在更改值对象时我需要创建一个全新的对象。在数据库中,这意味着我会得到很多孤立的条目,除非我删除旧记录。
  • 并非如此 - 它仍然是不可变的。想想'字符串'。当您“编辑”一个字符串时,它实际上是一个新对象。因此,在数据库中“编辑”值对象与删除后跟插入相同。 “ID”是值。你不会有单独的钥匙。
【解决方案2】:

您不会更改值对象。您创建一个具有不同值的新值。如果值对象的属性很少需要经常更改,那么一些辅助方法很有用。 myObject.WithX(4711) 将创建一个新实例,其所有属性都与 myObject 相同,但例如 X 属性更改为 4711。 要在 UI 中“编辑”值对象,请使用视图模型。 Viewmodel 不是值对象(顺便说一句,也不是实体),也不属于您的域。它纯粹在表示层中。它是可编辑和可变的。它可以有一个构造函数,从你的(不可变的)值对象中复制它的值,它可以有一个 ToXXX 方法来创建一个具有当前(和更改的)值的新(不可变)值对象。 如果您想将值对象存储在单独的表中(而不是展开存储拥有实体的表中的字段),这纯粹与数据访问层相关,而不是您的域模型的一部分。这可以通过映射来完成。在值对象中,数据库 id 是不可变的,在领域模型中没有任何意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多