gpt4 book ai didi

c# - 聚合根具有复合主键的存储库

转载 作者:行者123 更新时间:2023-11-30 16:07:55 25 4
gpt4 key购买 nike

存储库应该作为聚合根的边界,即 IRepository<TAggreagte>将提供以事务方式将数据保存到数据库的 CRUD 功能。到目前为止一切顺利。

但是如果聚合有一个复合主键呢?在我的问题中,它是一个标识 INT 列加上一个 SMALLINT 序列号。 (这是DB设计,不是我的主意!)

我见过的存储库示例有例如void Add(TAggregate aggregate)bool Add(TAggregate aggregate) .

使用“最终一致性”的示例:

我想添加一个聚合A,我需要调用存储库A,然后插入一个依赖 聚合B 使用 repository B,插入后我必须知道 aggregate A 的 ID。

这就是我迷路的地方。如果你插入 A,你将如何获得它的 ID,特别是如果它是一个组合键?我看到的唯一解决方案是再次返回整个对象,因此:

TAggregate Add(TAggregate a);

有什么建议吗?

最佳答案

Identity 在 DDD 中是一个非常棘手的话题。

关于身份创建的“时机”,有两种思想流派:

  • 标识是在创建该实体类的实例时生成的,或者
  • 身份是在它被持久化时创建的(例如,当它被插入到关系数据库中时)。

第二种方法会导致很多问题。你已经提出的一个。当仅在持久化时建立身份时,还会出现其他一些实际问题。考虑域实体的这两个核心属性:

  • 实体以其身份来区分。因此,没有身份就不能存在实体。
  • 当实体的标识相等时,实体被视为相等。

当使用“基于持久性的身份”方法创建实体类的新实例时,您最初没有身份,因此违反了上述所有原则。身份现在在您的实体中是否被建模为某种程度上是可选的?在我看来,这种方法会将您引向一条非常黑暗的道路。

有效解决这些问题的唯一方法是在实例化时生成标识。这也将解决您的问题。身份将立即提供给您。

如果您的数据库技术自动生成 ID,这对您来说可能会很棘手。

有几种方法可以在实体实例化时生成标识。

在实体内生成身份:

简单的例子:

public Person : DomainEntity<Guid>
{
//..
public Person(string name)
: base(Guid.New()) // Providing a unique GUID
{
Name = name;
}
}

客户端代码:

// A new person with identity!
var person = new Person("Eric Evans");

这是首选方法,但并非总是可行。

您向实体提供身份:

简单的例子:

public Person : DomainEntity<int>
{
//..
public Person(int identity, string name)
: base(identity) // Providing a unique GUID
{
Name = name;
}
}

客户端代码:

// A new person with identity!
var person = new Person(IdentityGenerator.Create(), "Eric Evans");

IdentityGenerator生成器可能会与您的数据库交互以获取并保留“下一个”身份(不幸的是,SQL Server 不支持这种身份)。

你站在哪里?

关于你有没有组合键,你需要问的问题是“我能在实例化时生成或提供实体身份吗?”

关于c# - 聚合根具有复合主键的存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30111563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com