领域驱动设计自动递增实体键

Domain Driven Design Auto Incremented Entity Key

刚开始使用域驱动设计,我了解到您应该使模型保持有效状态,并且在创建 class 的新实例时,建议将所有必需的属性作为构造函数参数。

但是,在使用自动递增键时,当我从我的持久层调用 Add 方法时,我只有这个新 ID。如果我在没有密钥的情况下实例化我的对象,我认为它们将处于无效状态,因为它们需要某种唯一标识符。

我应该如何实现我的体系结构以便在创建我的实体的新实例之前拥有我的 ID?

生成的随机 ID

这里实用的方法是使用随机 ID 并在实例化实体之前生成它们,例如在工厂。 GUID 是一个常见的选择。

在你提问之前:No, you won't run out of GUIDs :-)

带有 ID 预留的顺序 ID

如果您出于某种原因必须使用顺序 ID,那么您还有以下选择:

  • 查询数据库上的序列以获取下一个 ID。这取决于您的数据库产品,例如 Oracle 就有。
  • 创建一个 table,其中包含您仅用作密钥预留的自动递增密钥 table。要获得 ID,请在其中插入一行 table - 生成的密钥现在已为您保留,因此您可以将其用作实体的 ID。

请注意,这两种顺序 ID 方法都需要在开始创建实体之前进行数据库往返。这就是随机 ID 通常更简单的原因。因此,如果可以,请使用随机 ID。

DB 生成的 ID

另一种可能性是接受这样一个事实,即您在创建时没有 ID,但只有当对 DB 的插入操作成功时。根据我的经验,这使得实体创建使用起来很尴尬,所以我避免了它。但对于非常简单的情况,这可能是一种有效的方法。

除了 theDmi 的评论

1) 你可以在你的工厂方法中确保你的实体被存储到数据库中。这可能适用于也可能不适用于您的域,但如果您确定该实体将被保存,那可能是一种有效的方法

2) 可以把ID和数据库的主键分开。我曾处理过一个案例,如果客户付款,则只有订单,此时它将由发票 ID(连续 ID)标识。这并不意味着在数据库中我需要一个列 ID,它也是对象的主键。您可以在数据库中有一个主键(随机 guid),直到有一个 ID(int?)是连续的,如果尚未填充则为 null。