【问题标题】:using List<ValueObject> inside an entity DDD在实体 DDD 中使用 List<ValueObject>
【发布时间】:2022-01-15 15:36:28
【问题描述】:

我们可以在实体内部使用List&lt;ValueObject&gt; 吗?或者我们应该将它们用作List&lt;entity&gt;

当我在“Product”实体类中使用“List&lt;Discount&gt;”时,实体框架会使用生成的列 ID 创建一个“折扣”表。

我可以将折扣定义为价值对象列表吗? 当值对象用作列表时,将其用作具有标识的实体会更好吗?

第二个问题是关于更新实体内部的“List&lt;Discont&gt;”。如何在其实体中更新此值对象列表(添加、删除折扣)? 谢谢

【问题讨论】:

  • DDD 人 - 总是希望其他人遵循他们的原则,而不是相反。假设您不使用 EF Core,您将如何将“值对象”列表存储在关系数据库中?当您意识到这一点时,您就会明白为什么 EF Core 创建表(并且每个表都必须有主键)。有关最接近的 EF Core 术语(不同于 DDD)的更多信息,请参阅Collections of owned types
  • @IvanStoev 感谢您发布链接。我用过OwnsMany()。但是这个影子属性,不违反使用值对象的规则吗?在这种情况下,我应该通过影子属性“id”更新这个值对象列表吗?
  • @IvanStoev 这样我就可以通过这个属性添加、删除或者更新列表了!它违反了值对象的不变性及其对所有者的依赖。这是真的?如果没有,我该如何更新 valueobject 列表?谢谢
  • 我想说的是 DDD 概念、值对象等不是 EF Core 关注的问题。 EF Core 实体(拥有与否)代表数据模型,而不是域模型。那里没有“价值对象”——一切都是实体。如果你想使用 EF Core 从数据库存储/加载你的东西而不违反你的原则,那么创建单独的模型并使用 EF Core 数据模型来加载/持久化你的域实体。
  • 在询问 EF 问题时提及您正在使用的数据库变得越来越重要。我可以想象,对值类型列表的支持可以添加到 Cosmos db 提供程序中,因为它已经支持原始类型列表。但我假设您的目标是关系数据库。

标签: entity-framework-core domain-driven-design entity asp.net-core-5.0 value-objects


【解决方案1】:

正如@Ivan Stoev 在 cmets 中所述,您的域模型不是您的数据库模型。您需要以面向对象的方式为您的域建模,理想情况下,不考虑数据库。顺便说一句,在Value Object 中有一些标识符不会使其成为Entity。但是,Entity 始终需要该实体集中的唯一标识符,但标识符不是使类成为实体的定义因素(即它是否具有自己的生命周期)。

在现实世界中,一般指导需要务实。例如,如果您的值对象需要某种类型的标识符,那很好。但是,可能已经有可以使用的东西。在OrderItem 中,人们会使用ProductId,因为每个产品应该只有一个项目。在您的Discount 场景中,可能有一个DiscountType,其中只允许唯一的折扣类型。关于可变值对象,值对象通常不可变的原因是它表示特定值。你永远不会改变10,因为那将是另一个值。当您需要15 时,似乎有人会将10 更改为15,但实际上15另一个 值对象。同样,需要务实,在许多情况下,我们最终会使用Value Object,它不像单个值那么原始,因此更改值对象上的某些内容可能是有意义的。订单项目当然不是实体,但需要经常更改项目上的Quantity。好吧,这可能是关于 Quote/CartOrder 的另一个讨论,但这些概念仍然适用。

另一方面,我现在倾向于将仅存在于聚合中的任何“值对象”定义为聚合中的嵌套类。我不会有OrderOrderItem 类,而是Item 类中的Order 类...Order.Item。虽然这是一个设计选择,但我想我会提到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 2011-01-23
    • 2011-01-20
    • 2021-10-31
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    相关资源
    最近更新 更多