DDD:主键(Ids)和ORM(例如,NHibernate)

为什么在域实体中有一个Id字段呢?
我已经看到几个解决方案,为基类提供基于Id和Id的GetHashCode / Equals。

我对领域模型的理解是它应该只包含与域相关的内容。虽然在极少数情况下(可跟踪订单)Ids是有意义的,但绝大多数情况下,它们不提供任何东西,除了简单的方法来引用DB / UI上的对象。

我看不到Equals / GetHashCode也有好处,因为Identity Map的实现应该保证引用的等式是id的等级。

奇怪的是,我不能轻易找到其他人对这个问题的看法,所以我在这里问。在域实体中使用非域相关ID的一般意见是什么?如果我不向我的域实体添加ID,NHibernate是否有任何问题?

更新:

感谢您的答案。

其中几个建议使用Id是ORM进行数据库更新的唯一方法。我不认为是这样。 ORM已经跟踪从DB加载的所有实体,所以当它需要一个时,它应该很容易在内部获得Id。

更新2:

回答正义和类似的观点:
如果我们有一个Web应用程序,需要一种方式来引用会话之间的实体呢?像编辑/资源/ id?

那么我认为这是一个具体的UI /环境限制的需求,而不是域模型的需要。拥有GetIdentitity方法(与Load(identity)方法一致)的应用程序服务或存储库似乎足以满足此情况。

我只是谈谈NHibernate。在那里,您需要一个主键的字段,如果您采用业务数据(不推荐)或无业务意义的代理键,则由您决定。

典型情况是:

>数据库生成自动递增值
>由NHibernate生成的guid
>由业务逻辑生成的guid

拥有唯一身份证号码有很大的优势。当您将对象传递到客户端并返回服务器时,不能依赖内存标识。你甚至可以有几个实例记住同一个业务实例。业务实例由id标识。

基于Id的比较是一个味道的问题。我个人喜欢简单可靠的代码,基于id的比较是简单可靠的,而深度比较总是有点冒险,容易出错,不可维护。所以你最终与operator ==比较内存身份和Equals比较业务(和数据库)身份。

NHibernate是将类模型映射到我所知道的关系数据库的方式。在我们的大型项目中,我们拥有主键和版本属性(用于乐观锁定)。您可以认为这是侵扰性的,因为它不用于业务逻辑。

NH不需要具有这些性质。 (但它需要其中一个属性作为主键)。但是请考虑:

它只是工作更好,例如。悲观的锁定只有在适当的财产,
更快:int id在许多数据库上表现更好,然后是其他数据类型
>而且更容易:由于几个原因,不愿意对业务有意义的财产。

那么为什么要使你的生活比必要更难?

编辑:只读the documentation,发现NHibernate在持久化类中不需要id属性!如果你没有打字机,you can’t use some features.建议有它,只是让你的生活更轻松。

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...