繁体   English   中英

DDD - 如何在 EF Core 中跨有界上下文管理实体

[英]DDD - How to manage entities across bounded contexts in EF Core

我还没有找到具体的例子。 我知道每个有界上下文都有自己的实体版本,您不应该跨上下文共享实体。 但是我如何管理与使用像 EF 这样的 ORM 相关的问题?

例如,下面是我的实体和它们存在的有界上下文:

成分(实体有界上下文 A)

配方(实体有界上下文 b)
成分(实体有界上下文 b)
MenuItem(聚合有界上下文 b)

现在每个有界上下文都有自己的成分版本。 但是由于我在 EF 中有一个单一的数据库上下文来管理这个,我究竟该如何安排呢? 我正在使用 CQRS,因此我可以在需要时触发事件。 我的计划是在我的 Recipe 实体中维护一个 id 列表,并从数据库中提取相关的成分,以便数据不会重复。

但我不确定我的数据重复问题是否有效。 在我上面的例子中,假设一家企业销售原料,但也有可以在食品摊位出售的预设食谱(带有原料清单)。

在一个上下文中,成分与另一个实体没有关系,而在另一个上下文中它是一个子实体(在聚合中)。 我可以看到它应该如何设计(有界上下文中的单独实体)但是当涉及到数据库时,这实际上是如何设置的? 如果需要在上下文 A 和上下文 B 中跟踪成分的属性/领域知识不同怎么办? 这最终会成为一个单独的表吗? 我有点迷失了。

编辑:请记住,我在这里只使用了 1 个数据库。 我知道通常每个有界上下文都有单独的 DB 以避免这种情况,但想知道如何通过 1 DB 来实现这一点。

我将您的问题分为两部分:

  1. 架构部分:有界上下文设计/边界
  2. 技术部分:数据库模式管理、EF映射等

从第 1 点开始,我要强调的是,有界上下文边界比您在问题中暗示的要厚。 如果边界明确定义,那么 BC 之间几乎没有数据重复,一些 Id 的一部分等等。 在您的情况下,BC-A 中的成分与 BC-B 中的成分具有相同的 ID。

例如,您的 BC-A 可能会管理成分的名称、描述、图片等。 BC-B 不需要此信息,但它可能具有创建配方所需的一些重要属性。 以类似的方式,BC-C 可能包含每种成分的供应商、价格等。

此外,在您的 BC-B 中,您可能将成分放在两个位置:一张包含所有成分及其有趣属性的表格,以及作为食谱一部分的实体。 例如,该实体不会具有所有这些属性,而是具有成分 ID 加上该配方中使用的数量。

使用这种类型的设置,不仅在原则上是不可取的,甚至在实践中,跨限界上下文共享成分表也是不可取的。

很多时候,数据复制的需求来自UI需求。 例如,当您显示 Recipes 时,您将需要显示 Ingredient 的名称,但这可以通过 UI 组合来解决。 UI 可以从 BC-B 中提取食谱,并使用 BC-A 中的名称以及 BC-C 中的价格丰富数据。

如果您遵循这种方法,则第 2 点应该是独立的:每个 BC 都应该有自己的 DbContext。 可以对所有 DbContext 使用相同的连接字符串(数据库),但您可以使用特定的 DB 模式初始化 DbContext。 这样,您可以在每个 BC 中拥有一个成分表而不会发生 DB 表冲突,并且您也可以为每个 DbContext 拥有 EF 迁移版本表(尽管我相信它也适用于共享表)。 此设置还为您提供了一个优势,即允许您将每个有界上下文的单个数据库中的数据库分开,而无需更改任何代码。 出于可扩展性的原因,或者为了促进基础设施即代码等,您最终可能需要它。

TL/DR:拥有单个 db 服务是完全可以的(对于较小的服务或由于某些特定于业务的原因),只要数据不共享 如果您使用正常形式的数据库,请使用不同的表来存储您的两种成分。

更长的版本:

如果这两个有界上下文中的ingredient实体由同一个物理表支持,而且它们可以共享数据(一个成分实体可以对另一个成分实体创建的数据进行操作),那么它们就不是真正独立的。

以 BC 作为边界的一个非常重要的方面是准确地允许这些实体独立发展。 通过让他们共享一个表(或文档集合),您不允许这种情况发生。 此外,这违反了“您不应跨服务边界共享数据库”的更通用(我的意思是非 DDD 特定的)准则。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM