Lazy-loaded NHibernate properties in Equals and GetHashCode

后端 未结 3 1472
夕颜
夕颜 2021-01-03 03:49

How can the following problem be dealt with?

We\'re using lazy loaded NHibernate properties and whenever we\'re calling Equals() or GetHashCode()<

3条回答
  •  情歌与酒
    2021-01-03 04:34

    Two entities are equal if they are of the same type and has the same primary key.

    If you have integers for keys:

    1. Check for reference equality like you do now
    2. If you have the Equal method in some base class you check that the types you're comparing are equal. Here you can get in to trouble with proxies, I'll return to that
    3. Check if the primary keys are equal - that will not cause any lazy-loading

    If you have GUIDs for keys:

    1. Check for reference equality like you do now
    2. Check if the primary keys are equal - that will not cause any lazy-loading

    If I have integers for keys I usually have something like this Equal-override in a base class for my entities:

    public virtual bool Equals(EntityBase other)
    {
        if (other == null)
        {
            return false;
        }
    
        if (ReferenceEquals(other, this))
        {
            return true;
        }
    
        var otherType = NHibernateProxyHelper.GetClassWithoutInitializingProxy(other);
        var thisType = NHibernateProxyHelper.GetClassWithoutInitializingProxy(this);
        if (!otherType.Equals(thisType))
        {
            return false;
        }
    
        bool otherIsTransient = Equals(other.Id, 0);
        bool thisIsTransient = Equals(Id, 0);
        if (otherIsTransient || thisIsTransient)
            return false;
    
        return other.Id.Equals(Id);
    }
    

    Now if you entities that inherit from others using table per hierarchy you will face the problem that GetClassWithoutInitializingProxy will return the base class of the hierarchy if it's a proxy and the more specific type if it's a loaded entity. In one project I got around that by traversing the hierarchy and thus always comparing the base types - proxy or not.

    In these days though I would always go for using GUIDs as keys and do as described here: http://nhibernate.info/doc/patternsandpractices/identity-field-equality-and-hash-code.html

    Then there is no proxy type mismatch problem.

提交回复
热议问题