我发现很多帖子都解释说应该总是在NHibernate实体类上重写Equals / GetHashCode。如果我不使用套装,这真的有必要吗?
我根本找不到一个示例,其中显示缺少Equals / GetHashCode会导致意外和错误的行为。如果没有它们,一切似乎都能完美运行。这真的很奇怪,每个人都说这是必要的,但是没有人可以提供一个样本,显示为什么需要。
答案 0 :(得分:11)
最近有一个关于NHibernate的question做了选择N + 1,即使指定了fetch
也是如此。问题was缺少Equals
/ GetHashCode
实施。
答案链接到另一个类似的question。
此处another question Equals
/ GetHashCode
覆盖背后的推理。
Nhibernate n+1 with ternary relationship. Want the middle entity in the ternary
Nhibernate producing proxy despite HQL fetch
NHibernate: Reasons for overriding Equals and GetHashCode
Why Equals and GetHashCode are so important to NHibernate
Why is it important to override GetHashCode when Equals method is overridden?
修改强>
您不需要一直覆盖它们。如果您使用复合键,具有分离实体的多个会话或无状态会话,则可能是必要的。
如果您只使用单个会话,NHibernate会使用身份映射将实体存储到第一级缓存。在这种情况下,实体比较是通过比较ID来完成的。
在上述情况下(分离实体,无状态会话),NHibernate会比较实际实体,而不是它们的ID。默认情况下,Object.Equals
确实引用相等性。因此,如果两个对象指向完全相同的实例,则它们是相等的。您可能有两个具有相同标识的实例,但Object.Equals
将为它们返回false
。这与Entity
definition:
一个未由其属性定义的对象,而是由一个 连续性及其身份的线索。
JBoss Hibernate wiki在Equals
和HashCode
上有a good explanation,代码示例很少。
答案 1 :(得分:4)
事实上,只有极少数情况会导致副作用。但如果你得到它们,它们就会非常微妙。除了复合主键和字典键之外,它们总是需要正确的Equals / GetHashCode实现。
NH只关心在内存中实例化一个实体,因此默认参考比较应该有效...... 如果没有延迟加载。
如果不覆盖Equals,则在处理代理时会遇到问题。总有两个实例:代理和真实实体。它们都代表同一个实体。只有使用正确实现的Equals方法,才会将其视为相同。