在域驱动设计中,实体的一个定义特征是它具有身份.
问题:
我无法在实例创建时为实体提供唯一标识.一旦实体被持久化(此值由底层数据库提供),此标识仅由存储库提供.
此时我无法开始使用Guid值.现有数据与int主键值一起存储,我无法在实例化时生成唯一的int.
我的解决方案
代码(所有实体的抽象基类):
public abstract class Entity<IdType>
{
private readonly IdType uniqueId;
public IdType Id
{
get
{
return uniqueId;
}
}
public Entity()
{
uniqueId = default(IdType);
}
public Entity(IdType id)
{
if (object.Equals(id, default(IdType)))
{
throw new ArgumentException("The Id of a Domain Model cannot be the default value");
}
uniqueId = id;
}
public override bool Equals(object obj)
{
if (uniqueId.Equals(default(IdType)))
{
var entity = obj …Run Code Online (Sandbox Code Playgroud) c# domain-driven-design aggregateroot repository-pattern domain-model
最好的例子是User需要持久化的实体.我有以下候选人为用户分配唯一标识符:
举一个详细视图的简单示例,我们经常有一个用户的详细显示some/path/users/{user_id},如果我们将emailId保持为唯一ID,那么用户可能有一天会更改其电子邮件ID并将其中断.
哪种方法可以更好地识别同一个实体?
public class AggregateRoot {
private Integer id;
private Set<Child> children;
}
public class Child {
private Integer id;
private String name;
}
Run Code Online (Sandbox Code Playgroud)
想象一下,您需要保存Child他的 ID 并将其发送到某个外部系统。在 DDD 中,您将使用与此类似的代码保存孩子:
AggregateRoot aggregateRoot = aggregateRootRepository.getById(id);
Child child = new Child();
child.setName("Sun");
aggregateRoot.addChild(child);
aggregateRootRepository.save(aggregateRoot);
externalService.postSavedChildId(child.getId());
Run Code Online (Sandbox Code Playgroud)
当然child.getId()会返回 null 因为它不在持久化上下文中。知道如何在 DDD 中处理这种情况吗?