DDD:如何保存聚合的顺序?
DDD: How to save the order of aggregates?
我有两个聚合 'notebook' 和 'note'。
当我使用角色'aggregates reference only by there ids'时,我想我有两个选择:
Notebook(List<NoteId>, [other properties])
Note([other properties])
或
Notebook([other properties])
Note(NotebookId, [other properties])
对于第一个选项,我需要两次数据库调用来显示笔记本的所有笔记(一次获取列表,第二次加载笔记)。
所以我目前最喜欢的是第二个选项。现在我脑子里没有几个选项可以保存笔记的顺序,任何人都有一些缺点。
解决我的问题的好方法是什么?或者第一个选项更好,两个数据库调用可以忽略不计?
有人可以帮忙吗?
非常感谢
看来 Notes 的顺序很重要,至少与 Notebook 相关,所以也许它应该是域的一部分。如果是,我建议将它与Note一起存储。或者在加载列表时使用注释的一些其他信息来排序。
如果不是,为什么订单相关?我的意思是,这两个实体有一个相关但独立的生命周期,或者至少看起来:一个聚合体——Notebook——有一个列表,只引用另一个——Note。因此,没有计划进行直接互动。但是,鉴于域已正确建模(没有足够的信息来说明它),在某个地方您需要一个有序的注释列表。根据需要使用它的唯一方法是存储信息(或使用已经存储的信息),否则假设(顺序相关)不再有效。
更新有关笔记数量及其大小的信息
看起来您的域是这样组织的:
- 一个根实体,Notebook,其中还存储了每个 Note 的顺序,只有它的 ID:顺序的任何更改将从这里更新,而不是从 Note
- 另一个根实体,Note,有自己的生命周期和自己的'actions'(触发实体变化的操作)
无论何时加载 Notebook,都必须同时加载 Note 和它的顺序以正确显示它的顺序。另一方面,当您更改顺序时,此结构允许您在笔记本上执行单个操作(或操作),例如 changeOrder(NoteId),更新顺序给定的注释,如果需要,更改所有其他注释的顺序。这里的诀窍是,当您持久化 Notebook 时,您只需使用 Note 的 ID,因此您不必加载所有实体,而只需加载其中的一部分,更新并再次保存它。所以,Note 实体有多大并不重要,因为你不会全部使用它。因此,在每次更改时,您都可以触发该笔记本的所有对(NoteID、订单)的更新。你不能做不同的事情。但是,为了支持这一点,您需要在存储库中有一个函数,您可以在其中加载注释的 ID 及其顺序,然后再次保存它;那应该不会那么贵。
另一方面,所有直接在Note上操作的动作都应该加载它,所以你必须全部加载。但是在这种情况下需要加载所有,并保存所有,因为你正在更改 Note 本身。
无论如何,持久化订单的方式完全需要建立在域上的持久化层。我的意思是,该域有一个笔记本和一组顺序为 1、2、3 等的笔记。
即使我不认为这需要如此复杂的解决方案,您也可以使用完全不同的方式来存储订单:例如,您可以使用 100 步(因此 100、200、300 等) :每一个新的笔记都放在旧的两个笔记的中间,并且每次都是唯一被保存的。每隔一段时间你就会 运行 一份工作,或者其他什么东西,它只是标准化所有恢复 100 步的值(或者你用来保存订单的任何东西)。正如我所说,这看起来是一个过于复杂的问题解决方案,但它也显示了域的实体可能与持久性实体完全不同的事实。
我有两个聚合 'notebook' 和 'note'。
当我使用角色'aggregates reference only by there ids'时,我想我有两个选择:
Notebook(List<NoteId>, [other properties])
Note([other properties])
或
Notebook([other properties])
Note(NotebookId, [other properties])
对于第一个选项,我需要两次数据库调用来显示笔记本的所有笔记(一次获取列表,第二次加载笔记)。
所以我目前最喜欢的是第二个选项。现在我脑子里没有几个选项可以保存笔记的顺序,任何人都有一些缺点。
解决我的问题的好方法是什么?或者第一个选项更好,两个数据库调用可以忽略不计?
有人可以帮忙吗?
非常感谢
看来 Notes 的顺序很重要,至少与 Notebook 相关,所以也许它应该是域的一部分。如果是,我建议将它与Note一起存储。或者在加载列表时使用注释的一些其他信息来排序。
如果不是,为什么订单相关?我的意思是,这两个实体有一个相关但独立的生命周期,或者至少看起来:一个聚合体——Notebook——有一个列表,只引用另一个——Note。因此,没有计划进行直接互动。但是,鉴于域已正确建模(没有足够的信息来说明它),在某个地方您需要一个有序的注释列表。根据需要使用它的唯一方法是存储信息(或使用已经存储的信息),否则假设(顺序相关)不再有效。
更新有关笔记数量及其大小的信息
看起来您的域是这样组织的:
- 一个根实体,Notebook,其中还存储了每个 Note 的顺序,只有它的 ID:顺序的任何更改将从这里更新,而不是从 Note
- 另一个根实体,Note,有自己的生命周期和自己的'actions'(触发实体变化的操作)
无论何时加载 Notebook,都必须同时加载 Note 和它的顺序以正确显示它的顺序。另一方面,当您更改顺序时,此结构允许您在笔记本上执行单个操作(或操作),例如 changeOrder(NoteId),更新顺序给定的注释,如果需要,更改所有其他注释的顺序。这里的诀窍是,当您持久化 Notebook 时,您只需使用 Note 的 ID,因此您不必加载所有实体,而只需加载其中的一部分,更新并再次保存它。所以,Note 实体有多大并不重要,因为你不会全部使用它。因此,在每次更改时,您都可以触发该笔记本的所有对(NoteID、订单)的更新。你不能做不同的事情。但是,为了支持这一点,您需要在存储库中有一个函数,您可以在其中加载注释的 ID 及其顺序,然后再次保存它;那应该不会那么贵。
另一方面,所有直接在Note上操作的动作都应该加载它,所以你必须全部加载。但是在这种情况下需要加载所有,并保存所有,因为你正在更改 Note 本身。
无论如何,持久化订单的方式完全需要建立在域上的持久化层。我的意思是,该域有一个笔记本和一组顺序为 1、2、3 等的笔记。
即使我不认为这需要如此复杂的解决方案,您也可以使用完全不同的方式来存储订单:例如,您可以使用 100 步(因此 100、200、300 等) :每一个新的笔记都放在旧的两个笔记的中间,并且每次都是唯一被保存的。每隔一段时间你就会 运行 一份工作,或者其他什么东西,它只是标准化所有恢复 100 步的值(或者你用来保存订单的任何东西)。正如我所说,这看起来是一个过于复杂的问题解决方案,但它也显示了域的实体可能与持久性实体完全不同的事实。