【问题标题】:nhibernate gethashcode behaviour休眠 gethashcode 行为
【发布时间】:2011-09-10 06:28:54
【问题描述】:

在过去的 3 天里,我一直在为一种有趣的行为而苦苦挣扎,至少对我来说是这样。 基本概念如下:在内存中创建一个对象,这个对象有一个子列表。这个对象被保存到数据库中,孩子也被保存,级联模式。 这工作正常,但如果在我保存之后我尝试删除一个孩子,从列表中删除,这不起作用,列表不会删除孩子。 我发现,HashedSet 类型的列表以某种方式缓存对象的哈希码,当它第一次插入列表时,在保存之前,在保存之后,相同的对象没有相同的哈希码。但是该列表仍然假定旧的哈希码。 我已经覆盖了GetHashCodeEquals,经过大量的谷歌搜索和阅读,我找到了一个blog post,它解释了nhibernate 对GetHashCodeEquals 方法的使用。

这是我的实现

    public override int GetHashCode()
    {
        if (orgHashCode.HasValue)
            return orgHashCode.Value;

        var hashCode = 17;
        var signatureProperties = GetSignatureProperties();

        if (!IsTransient())
            hashCode = (hashCode*HASH_MULTIPLIER) ^ GetIdValue().GetHashCode();
        else
        {
            foreach (var property in signatureProperties)
            {
                object value = property.GetValue(this, null);

                if (value != null)
                    hashCode = (hashCode*HASH_MULTIPLIER) ^ value.GetHashCode();
            }
        }

        if (!orgHashCode.HasValue)
            orgHashCode = hashCode;


        // If no properties were flagged as being part of the signature of the object,
        // then simply return the hashcode of the base object as the hashcode.
        return signatureProperties.Any() ? hashCode : base.GetHashCode();
   }

    public override bool Equals(object obj)
    {
        var compareTo = obj as DbCommonBase;

        if (ReferenceEquals(this, compareTo))
            return true;

        return compareTo != null &&
                GetType().Equals(compareTo.GetUnproxiedType()) &&
                (HasSameNonDefaultIdAs(compareTo) || ((IsTransient()) || compareTo.IsTransient()) &&
                HasSameObjectSignatureAs(compareTo));
    }

我使用了一个名为 orgHashCode 的变量,它在生成第一个哈希码之前返回哈希码,如果我使用这种方法,它似乎可以工作,但我认为这不是最好的解决方案,应该为当前生成哈希码对象而不是它的“第一个版本”。

我不知道我的解释是否足够清楚。 任何提示将不胜感激。 谢谢

【问题讨论】:

    标签: nhibernate equals persistent gethashcode transient


    【解决方案1】:

    all-delete-orphan 有级联模式吗?这种级联模式允许在从集合中删除对象时删除它们。

    【讨论】:

    • 您好,感谢您的回复,我尝试了 Cascade.All 和 Cascade.AllDeleteOrphan,我使用的是 fluentNhibernate。问题仍然存在。问题不在于自身休眠。这就是发生在我身上的事情,如果我创建一个对象并将子对象添加到其子列表中,然后我将这个新对象保存在数据库中,这工作正常。但是,如果在这之后是在同一个休眠会话中,我会尝试删除它不会删除的孩子。
    • 因为保存孩子的列表在保存之前保留了孩子的哈希码,但保存后的孩子有不同的哈希码,所以如果我做一个列表的删除方法不起作用等于它为有问题的子对象返回 true
    【解决方案2】:

    刚刚找到了我的问题的答案, 保存子列表的字典中的问题,这使用对象的 HashCode 存储键,如果对象的 GetHashCode 被覆盖,就像我的情况一样,它应该返回一个在生命周期内应该是不可变的值对象,在我的情况下它没有发生。因此,当将项目添加到列表中时,GetHashCode 返回一个值,但是在我将对象保存到数据库后,GetHashCode 会发生变化,但字典仍然保存对象的原始 HashCode,如果我执行删除或包含,因为值是不同之处在于字典没有找到该对象,尽管它存在于列表中 This question 可以更好地解释我的问题

    【讨论】:

    猜你喜欢
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    相关资源
    最近更新 更多