Lazy-loaded NHibernate properties in Equals and GetHashCode

后端 未结 3 1467
夕颜
夕颜 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:21

    If you are using identity equality, you should be able to access the key without triggering a load:

    public virtual bool Equals(ClassB other)
    {
        if (ReferenceEquals(null, other))
        {
            return false;
        }
        if (ReferenceEquals(this, other))
        {
            return true;
        }
        // needs to check for null Id
        return Equals(other.ClassC.Id, ClassC.Id) && Equals(other.ClassD.Id, ClassD.Id);
    }
    

    You can handle comparisons between objects before and after persisting by caching the hash code when it was transient. This leaves a small gap in the Equals contract in that a comparison between an existing object that was transient will not generate the same hash code as a newly-retrieved version of the same object.

    public abstract class Entity
    {
        private int? _cachedHashCode;
    
        public virtual int EntityId { get; private set; }
    
        public virtual bool IsTransient { get { return EntityId == 0; } }
    
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }
            var other = obj as Entity;
            return Equals(other);
        }
    
        public virtual bool Equals(Entity other)
        {
            if (other == null)
            {
                return false;
            }
            if (IsTransient ^ other.IsTransient)
            {
                return false;
            }
            if (IsTransient && other.IsTransient)
            {
                return ReferenceEquals(this, other);
            }
            return EntityId.Equals(other.EntityId);
        }
    
        public override int GetHashCode()
        {
            if (!_cachedHashCode.HasValue)
            {
                _cachedHashCode = IsTransient ? base.GetHashCode() : EntityId.GetHashCode();
            }
            return _cachedHashCode.Value;
        }
    }
    

提交回复
热议问题