nhibernate gethashcode行为

nhibernate gethashcode行为,nhibernate,equals,persistent,gethashcode,transient,Nhibernate,Equals,Persistent,Gethashcode,Transient,在过去的三天里,我一直在为一种有趣的行为而挣扎,至少对我来说是这样。 基本概念如下:在内存中创建一个对象,这个对象有一个子对象列表。此对象保存到数据库中,子对象也保存在级联模式中。 这很好,但是如果在保存之后,我尝试删除一个子项,从列表中删除,这不起作用,列表不会删除该子项。 我发现列表HashedSet type以某种方式缓存对象的hashcode,当它第一次插入列表时,在保存之前,在保存之后,同一对象没有相同的hashcode。但是列表仍然采用旧的哈希代码。 我已经重写了GetHashCod

在过去的三天里,我一直在为一种有趣的行为而挣扎,至少对我来说是这样。 基本概念如下:在内存中创建一个对象,这个对象有一个子对象列表。此对象保存到数据库中,子对象也保存在级联模式中。 这很好,但是如果在保存之后,我尝试删除一个子项,从列表中删除,这不起作用,列表不会删除该子项。 我发现列表HashedSet type以某种方式缓存对象的hashcode,当它第一次插入列表时,在保存之前,在保存之后,同一对象没有相同的hashcode。但是列表仍然采用旧的哈希代码。 我已经重写了GetHashCode和Equals,经过大量的搜索和阅读,我发现了一个解释nhibernate使用GetHashCode和Equals方法的方法

这是我的实现

    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的变量,它在生成第一个hashcode之前返回hashcode,如果我使用这个方法,它似乎是有效的,但我认为这不是最好的解决方案,hashcode应该为当前对象生成,而不是为它的第一个版本生成

我不知道我的解释是否足够清楚。 如有任何提示,将不胜感激。
谢谢你有级联模式吗?此级联模式允许从集合中删除对象。

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

您好,谢谢您的回复,我尝试了Cascade.All和Cascade.AllDeleteOrphan,我正在使用fluentNhibernate。问题仍然存在。问题不在于它本身。这就是发生在我身上的事情,如果我创建了一个对象,并将child添加到它的子列表中,然后我将这个新对象持久化到数据库中,这就可以了。但是,如果在同一个nhibernate会话中,我尝试删除其中的一个孩子,则不会删除。因为保存孩子的列表保留了保存前孩子的哈希代码,但保存后孩子的哈希代码不同,因此,列表的remove方法始终不起作用,但如果我使用equals,它将为问题中的子对象返回true我不确定,我想您已经看到了它,但此链接可能会帮助您: