我们已将数据库中的Location
实体标识为我们域中的值对象(DDD)。其他域对象使用的位置,但不是真的独立的#34; - 他们总是属于另一个实体。
现在我们正在尝试在简单的MVC Web应用程序中编辑这些值的列表。因此,视图将在视图模型LocationViewModel
中显示位置列表。
但是,值对象根据定义不可变,但确实包含对另一个实体(Business
)的引用。
域:
public class Location : ValueObject<Location>
{
readonly locationId;
public int LocationId {get{return _locationId;}}
public Business Business {get;set;}
}
我的问题是了解如何在UI中简单地编辑一堆值对象并进行更改,例如:该位置所属的业务。 值对象不应该具有&#34;标识&#34;,但它确实需要ID,因此存储库可以更新数据库。
我也不认为您可以将位置设置为实体,因为您想在UI中对其进行编辑。或者是Location
,在这种情况下确实是一个实体?
我不理解的是什么?
谢谢!
答案 0 :(得分:0)
这是一个经典问题。在一个上下文中,它是一个实体,在另一个上下文中是一个值对象。我发现电话号码的例子有助于理解这类问题。
例如,在CRM中,电话号码是一个价值对象。同一个可以与多个联系人相关联。它因价值而异(这里的关键概念)。所以在这种情况下,它是一个价值对象。在这个例子中,我可以将电话号码存储在数据库和“ID”中。将是电话号码本身。如果值对象由多个部分组成,那么它们将形成一个复合键。
但是,如果我们查看电话公司的电话号码。那很可能是一个实体。它可以附加所有信息庄严。所有这些信息都会因ID而异(在这种情况下就是数字)。
在您的情况下,位置听起来像一个值对象。如果您需要将其作为一个事物而不是仅仅作为实体的一部分保存在数据库中,那么将它的部件用作复合键。你将需要处理当你改变时发生的事情。一个,因为它不是一个变化,而是创造新的价值对象。一种方法是删除旧的并插入新的。或者只保留所有版本。这取决于您的域名。
希望有所帮助。
答案 1 :(得分:0)
您不会更改值对象。您创建一个具有不同值的新的。如果值对象具有您希望经常更改的几个属性,则某些辅助方法很有用。 myObject.WithX(4711)将创建一个新实例,其所有属性与myObject相同,但X属性更改为4711。 要编辑&#34;您使用viewmodel的UI中的值对象。 Viewmodel不是值对象(顺便说一下,没有实体),也不是域的一部分。它完全在Presentation Layer中。它是可编辑和可变的。它可以有一个构造函数,使你的(不可变)值对象复制它的值,它可以有一个ToXXX方法来创建一个新的(不可变的)值对象及其当前(和更改的)值。 如果要将值对象存储在单独的表中(而不是在存储拥有实体的表中推出字段),这纯粹是与数据访问层相关的,而不是域模型的一部分。这可以通过映射来完成。在值对象中,数据库ID是不可变的,在域模型中没有意义。