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:
- check reference equality now
- if have equal method in base class check types you're comparing equal. here can in trouble proxies, i'll return that
- check if primary keys equal - not cause lazy-loading
if have guids keys:
- check reference equality now
- 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
Post a Comment