c# - Lazy-loaded NHibernate properties in Equals and GetHashCode -


how can following problem dealt with?

we're using lazy loaded nhibernate properties , whenever we're calling equals() or gethashcode() properties used, lazy-loaded, potentially causing cascade of lazy-loading operations. eager-loading used alternative, think in specific cases , not general solution.

a typical scenario this:

public class abstractsaveableobject {     [id(0, name = "id", unsavedvalue = null)]     [generator(1, class = "native")]     public virtual long? id { get; set; } }  [class(nametype = typeof(classa))] public class classa : abstractsavableobject {     [bag(0, inverse = true, cascade = "none")]     [key(1, column = "classa")]     [onetomany(2, classtype = typeof(classb))]     public virtual icollection<classb> classbs { get; set; } }  [class(nametype = typeof(classb))] public class classb : abstractsavableobject {      [manytoone(column = "classa")]     public virtual classa classa { get; set; }      [manytoone]     public virtual classc classc { get; set; }      [manytoone]     public virtual classd classd { get; set; }      public virtual bool equals(classb other)     {         if (referenceequals(null, other))         {             return false;         }         if (referenceequals(this, other))         {             return true;         }         return equals(other.classc, classc) && equals(other.classd, classd);     } } 

implementation of gethashcode , equals(object) have been omitted brevity.

what strategies can been used tackle issue?

two entities equal if of same type , has same primary key.

if have integers keys:

  1. check reference equality now
  2. if have equal method in base class check types you're comparing equal. here can in trouble proxies, i'll return that
  3. check if primary keys equal - not cause lazy-loading

if have guids keys:

  1. check reference equality now
  2. check if primary keys equal - not cause lazy-loading

if have integers keys have equal-override in base class 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 entities inherit others using table per hierarchy face problem getclasswithoutinitializingproxy return base class of hierarchy if it's proxy , more specific type if it's loaded entity. in 1 project got around traversing hierarchy , comparing base types - proxy or not.

in these days though go using guids keys , described here: http://nhibernate.info/doc/patternsandpractices/identity-field-equality-and-hash-code.html

then there no proxy type mismatch problem.


Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -