【发布时间】:2014-06-18 14:52:14
【问题描述】:
我很好奇人们对于将 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... 方法或 @ 来获得合法的域实体987654325@ 方法,否则如果您尝试更新/删除实体,它将引发异常。
我知道这可能是过度设计,我应该冷静下来,务实一点,我只是好奇其他人对此有何看法。
我不想仅仅为这个小问题开始另一个线程,因为它有些相关。但由于是最近我才开始研究 DDD(尽管在这种情况下我的数据库首先出现)我想知道我是否可以确认我对域实体有正确的心态,这是我的 Employee 域实体的一个简化示例。
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..
}
谢谢!
【问题讨论】:
-
如果您希望这个问题得到回答(并保持开放),您应该减少措辞并提出一个真正的问题(不是讨论)
-
@ShoeMay:我不同意。这是一个相关且结构良好的问题。那些实现 DDD 的概念通常会被这样的设计问题所困扰。
标签: c# persistence domain-driven-design repository-pattern