【问题标题】:Few confusing things about expressing relationships with References and Repositories关于表达与引用和存储库的关系的一些令人困惑的事情
【发布时间】:2013-02-09 02:41:41
【问题描述】:

• 我们可以通过对象引用来表达两个实体之间的关联(虽然聚合根与其内部实体之间的关系 也可以通过 在根上定义的方法 --> SomeRootEnt.BorrowMeIntEnt(...) )或通过 Repository 表示,这将检索 相关实体 em> 来自数据库。
• 当通过Repository表达关系时,client会直接调用Repository来获取相关实体 • 关于如何表达关系的决定是基于这种关系是否是维护完整性所必需的(也许还取决于行为需要联想才能表达自己)

1) 如果 repository 表示 relationship(比如 1:*),则需要 子实体包含 父实体ID (注意:这个问题假设至少有一个父实体是根,或者它们都位于同一个聚合中)?

2) 不同聚合中的实体之间的关系只能用IDs

表示

a) 为什么?

b) 这样的关系难道不是通过Repository来表达的吗?

c) 如果 b) 为“是”,这也表明在大多数情况下,不同聚合中的实体之间的关联 是不需要的为了支持特定的行为?如果是,为什么?

更新:

2a)

表示与身份引用的关系不同于 表示与对象引用的关系。原因是 关系应该用一个身份来表达是为了维持 事务完整性——即只有一个聚合将被修改 在任何给定的交易中。如果使用了对象引用,则两个 聚合可能会受到事务的影响。

我 - 我理解您要表达的观点,因为如果关系将用 对象引用 来表达,那么仅仅是因为聚合 A1(正在修改)是“物理上”连接到另一个聚合 A2,这意味着 A1 的一个部分(即 A2

II - 但是从概念上讲,如果我们修改A1,那么即使两者之间的关系不使用对象引用来表达,两个聚合仍然是不同步的,所以实际上, A1和A2物理连接有什么区别?

III - 无论如何,为什么我们不能在两种情况下都简单地使用最终一致性

第二次更新:

原始_2)

需要明确的是,根实体 (AR) 之间的关系应该是 用身份来表达。非根实体之间的引用 应该禁止不同的聚合。

我们能否拥有只能从 A1 非根实体A2 根实体 的单向关联(即 非根实体在 A1 中将包含 A2 根的 ID)?

2) 一)

我。

如果使用了对象引用,则两个聚合可能会受到 交易。

它创造了 A2 在事务中被修改的可能性 正在修改 A1。通过身份引用 A2 消除了这一点 可能性。此外,数据库锁定等内容不适用于 A2 加载 A1 时。

暂时忽略在更新 A1 时数据库锁定不适用于 A2 的事实 - 为什么我们不应该在某些情况下允许在单个事务中同时修改 A1 和 A2?

我知道聚合定义了一致性边界,但如果在极少数情况下我们需要 A1 和 A2 在同一个事务中同步,那么只有其他选择可能是将 A1 和 A2 转换为单个聚合,在该特定模型中可能不合适?!

谢谢

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

    1) 是的。例如,假设您有一个有订单的客户。要获取客户的所有订单,您可以通过订单存储库选择具有相应 CustomerId 的所有订单。

    2) 需要明确的是,根实体 (AR) 之间的关系应该用身份来表示。应该禁止不同聚合中的非根实体之间的引用。

    2a) 表达与标识引用的关系不同于表达与对象引用的关系。应该用身份表示关系的原因是为了维护事务完整性——即在任何给定事务中只会修改单个聚合。如果使用对象引用,则事务可能会影响两个聚合。

    2b) 是的。存储库允许遍历,身份表示关系。

    2c) 这是聚合的重点——它应该定义一个一致性边界。如果对聚合的更改会影响聚合,那么这些更改应该能够以最终一致的方式应用。

    更新

    2a1) 它创造了在修改 A1 的事务中修改 A2 的可能性。通过身份引用 A2 消除了这种可能性。此外,在加载 A1 时,数据库锁定等内容不会应用于 A2。

    2a2) 如果修改 A1 的事务导致需要应用到 A2 的更改,这些更改将被同步最终。将它们物理分开的原因在 2a1 中说明。

    2a3) 您可以再次说明 2a1 中指定的原因,解释为什么使用身份引用更好。

    更新 2

    2) 我想如果两个 AR 的完整性得到维护,并且引用使生活变得更轻松,这是可以接受的。引用本身不是问题,它可能会导致问题。

    2a1) 其原因之一在于更现代的文档数据库架构。文档数据库通常只支持单个文档上的原子事务。另一个原因是两个 AR 可能存储在不同的数据库中,在这种情况下,需要分布式事务来保持一致性。但是,关系数据库当然可以锁定多个表,因此在一个事务中修改两个 AR 的情况是可能的。因此,这些限制应被理解为指导方针。如果了解所有后果并谨慎行事,则可以接受更新两个 AR。

    【讨论】:

    • 这是可能的,但我认为在订单对象上有一个 CustomerId 很重要,至少对于声明性目的而言。
    • 是的,它声明了这种关系。 customerId 也可用于某些行为。
    • 保持完整性就可以了。特定情况可能会影响决策。
    • 可以,但也可以。要点是聚合应该被认为是概念上的整体。特定用例可能具有影响决策的独特特征。
    • 想一想,我看不出有什么问题,而且很常见。我正在考虑在另一个聚合中引用非根...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 2014-11-02
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 2019-11-07
    相关资源
    最近更新 更多