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

Hel*_*123 8 c# domain-driven-design entity-framework cqrs

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

例如,下面是我的实体及其存在的有界上下文:

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

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

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

但我不确定我的数据重复担忧是否有效。在上面的例子中,想象一家企业不仅销售原料,而且还拥有可以在食品摊上销售的预设食谱(带有原料列表)。

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

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

Fra*_*lls 4

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

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

从第一点开始,我要强调的是,有界上下文边界比您在问题中暗示的更厚。如果边界定义良好,BC 之间几乎没有数据重复,部分数据来自某些 Id,仅此而已。就您而言,BC-A 中的成分与 BC-B 中的成分具有相同的 ID。

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

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

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

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

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