c#-聚集根具有复合主键的存储库
作者:互联网
信息库应该作为聚合根的边界,即IRepository< TAggreagte>.将提供CRUD功能,以事务方式将数据保存到DB.到现在为止还挺好.
但是,如果聚合具有复合主键怎么办?
在我的问题中,它是一个Identity INT列以及一个SMALLINT序列号. (这是数据库设计,不是我的主意!)
我见过的存储库示例都有例如无效Add(TAggregate聚合)或bool Add(TAggregate聚合).
使用“最终一致性”的示例:
我想添加聚合A,并且需要调用存储库A,然后使用存储库B插入从属聚合B,我必须知道聚合A插入后的ID.
那是我迷路的地方.如果插入A,将如何获得其ID,特别是如果它是复合键?
我看到的唯一解决方案是再次返回整个对象,因此:
TAggregate Add(TAggregate a);
有什么建议吗?
解决方法:
在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不支持该身份).
你站在哪里?
关于是否具有组合密钥,您需要问的问题是“在实例化时我是否能够生成或提供实体身份?”
标签:aggregateroot,domain-driven-design,repository-pattern,eventual-consistency,c 来源: https://codeday.me/bug/20191120/2043341.html