DDD与存储库中的身份冲突

时间:2012-12-29 14:21:57

标签: .net domain-driven-design ddd-repositories

我在示例应用中遵循数据库优先方法。 POCO类是通过t4模板生成的,它将具有从数据库中携带的Identity属性。对于我在域中用作实体的某些类,id的类型可以是 int,string& GUID

我没有看到我可以在域中生成的字符串或Guid的id并将其传递给存储库的问题。在int的情况下我也可以这样做,但我想利用SQL数据库的 AUTOINCREMENT选项

我的问题是:

  1. 谁负责为实体生成身份。它是域还是存储库?

  2. 如何在存储库和域之间进行身份同步?例如,我可以为域中的 Customer 创建一个id为1000,并要求Repository保存它。当存储库保存它时,新标识可能是2000(AUTOINCREMENT选项设置新标识)。现在这两个实体是不同的,如果域中的Customer实体(假设它是为了将来的操作而缓存)与其他实体(如 Department )一起使用,则可能会导致域中出现问题。域中具有id为1000的缓存实体( Customer )将保存为SQL数据存储区中的新实体。存储库不知道客户是缓存的还是新的。

1 个答案:

答案 0 :(得分:2)

  

谁负责为实体生成身份。是吗   域名或存储库?

实体的身份可以由域直接或通过客户端请求分配。这种类型的身份通常使用Guid或另一个通用唯一值生成。存储库还可以分配标识以反映数据库生成的标识,例如增量标识列。

  

如何在存储库和存储库之间完成身份的同步   域名?

当实体的身份来自数据库生成的标识列时,域不应分配自己的标识。具有完整标识的瞬态实体最初将具有标识值0.当瞬态实体变为持久性时,存储库将分配标识值。此时,正如您所指出的,由于身份值已更改,因此新持久化实体实例的缓存实例可能存在一些问题。有几种方法可以解决这些问题,但我尽量避免在第一个地方的缓存(或其他任何地方)中引用临时实体。这可以通过确保实体在许多地方未被引用直到它被持久化来更容易地完成。如果最终在各个位置引用临时实体实例,则可以确保其.NET运行时标识在实例的生命周期内保持不变。为此,您必须在身份值检查之前通过object.ReferenceEquals比较实体,并且必须在对象生存期内缓存通过GetHashCode生成的哈希码。