我很好奇人们对将 DAL 实体的 ID 保留为域实体的属性,最多只读属性的想法。
我的第一个想法是这样做没问题,但我越想越不喜欢这个想法。毕竟域模型应该完全不知道数据是如何持久化的,并且在每个域模型上保留和 Id 属性是一个不太微妙的指示。持久层可能不需要主键,或者域模型中公开的另一个属性可能是识别的合适候选者,模型编号。也许吧。
但这让我开始思考,对于没有可靠方法唯一标识数据库持久层条目的域模型,在更新或删除时它们如何标识条目?
基于弱引用键的字典可以解决问题; WeakDictionary<DomainEntity, PrimaryKeyType>
.每当存储库的客户端获取 DomainEntity
的集合时,该字典将成为存储库实现的一部分。对实体及其持久层 Id 的弱引用存储在这个内部字典中,这样当需要将修改后的实体返回到存储库以更新持久层时,可以执行以下操作来取回 Id
PrimaryKeyType id = default(PrimaryKeyType);
if (!weakDictionary.TryGetValue(someDomainEntity, out id))
// id not found, throw exception? custom or otherwise..
// id found, continue happily mapping domain model back to data model.
在我看来,这种方法的好处是域实体不需要维护其持久层特定的 id,并且存储库强制您通过调用 Fetch...
获得合法的域实体。方法或 Add/CreateNew
方法,否则如果您尝试更新/删除实体,它将抛出异常。
我知道这可能是过度设计,我应该冷静下来并务实一点,我只是想知道其他人对此有何看法。
我不想为这个小问题再开一个帖子,因为它有些相关。但由于是最近我才开始研究 DDD(虽然在这种情况下我的数据库排在第一位)我想知道我是否可以确认我对领域实体有正确的心态,这是我的员工领域实体的一个缩减示例。
public class Employee : DomainEntity
{
public string FirstName { get; }
public string LastName { get; }
public UserGroup Group { get; }
// etc..
// only construct valid employees
public Employee(string firstName, string lastName, SecureString password, UserGroup group);
// validate, update. (not sure about this one.. pulled it
// from an open source project, I think that names should be able to be set individually).
AssignName(string firstName, string lastName);
// validate, update.
ResetPassword(SecureString oldPassword, SecureString newPassword);
// etc..
}
谢谢!
最佳答案
您关于使用弱引用的提议存在一个重大缺陷。
您可能知道,领域实体的一个重要特征是它们必须具有身份。这对于比较原因很重要。如果两个实体具有相同的身份,无论它们的属性值如何,那么它们都被认为是相等的:
Entity1 == Entity2 ⇔ Entity1.Identity == Entity2.Identity
典型的“设计模式”是从 DomainEntity<T>
继承所有实体抽象类,它覆盖了这些对象的比较并通过身份进行比较。
现在,考虑使用弱引用查找的方法。让我们举个例子:
你获取一个 Entity1
,从存储库中说“Reegan Layzell”用户。然后您再次从存储库中获取完全相同的“Reegan Layzell”实体作为 Entity2
.您现在在域中的两个对象中拥有相同的实体。但是他们有不同的引用(当然)。
比较时,这些实体在您的域中不会被视为相等。
我很佩服您害怕将数据库问题引入您的域模型,但是将数据库 ID 传播到您的实体中几乎不会影响模型的质量,而且会为您省去很多麻烦.就像你说的,我们需要务实。
关于您的 Employee
示例:是否 AssignName
真的有意义吗?现实中,员工的姓名真的可以在创建后更改吗?除此之外,看起来你的想法是正确的。我强烈建议你看这个:Crafting Wicked Domain Models作者:吉米博加德。
关于c# - 持久性 ID 和域模型实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23419358/