0

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

这是我的实现

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

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

4

2 回答 2

0

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

于 2011-06-08T06:35:14.030 回答
0

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

于 2011-06-08T13:21:59.693 回答