Thanks, that solved the problem. I agree that once an object is initialized the value returned by GetHashCode should not change (actually Name has a private setter and is only assigned in one of the constructors or by NH when loading the entity), but here NH is forcing a GetHashCode evaluation (by using it as a dictionary key) before it assigns all the object's properties. This behavior is different than the one used when the dictionary is lazy-loaded... I just want to confirm that this behavior is by-design.
Anyway, I guess the documentation ( http://www.nhforge.org/doc/nh/en/index.html#persistent-classes-equalshashcode) would welcome an update :) On Sat, Feb 21, 2009 at 4:19 PM, Fabio Maulo <[email protected]> wrote: > private int? requestedHashCode; > public override int GetHashCode() > { > if (!requestedHashCode.HasValue) > { > requestedHashCode = IsTransient() ? base.GetHashCode() : Id.GetHashCode(); > } > return requestedHashCode.Value; > } > Or equivalent if you are working with Natural-Id. > > P.S. take care with string concatenation in hashcode (different > concatenated strings may return same hash). > > 2009/2/21 Ayende Rahien <[email protected]> > > You are doing something wrong. Equals & GetHashCode should not change, and >> should be based on the ID of the object. >> >> >> On Sat, Feb 21, 2009 at 1:44 PM, Germán Schuager <[email protected]>wrote: >> >>> Hi, I'm seeing some odd behavior and I can't figure out where the problem >>> is... >>> >>> >>> I have the following classes: >>> >>> public class Model >>> { >>> public virtual int ID { get; private set; } >>> >>> public virtual string Name { get; set; } >>> >>> ... >>> } >>> >>> public class Scheme >>> { >>> public virtual int ID { get; private set; } >>> >>> public virtual string Name { get; set; } >>> >>> private IDictionary<Model, decimal> rates = new Dictionary<Model, >>> decimal>(); >>> >>> public virtual IDictionary<Model, decimal> Rates >>> { >>> get >>> { >>> return rates; >>> } >>> } >>> >>> ... >>> } >>> >>> I'd like to fetch an scheme, the rate collection and the models in a >>> single select, so I have the following code: >>> >>> scheme = session.CreateQuery("from Scheme e left join fetch e.Rates r >>> left join fetch index(r) where e.Name = 'something'") >>> .UniqueResult<Scheme>(); >>> >>> Assert.That(scheme.Rates.Count, Is.EqualTo(2)); >>> >>> var firstKey = scheme.Rates.Keys.First(); >>> Assert.That(scheme.Rates.ContainsKey(firstKey)); <--- FAILS!!! >>> >>> The problem is that the 2nd Assert fails with a KeyNotFoundException. >>> >>> Doing some research/debugging, it seems that NH is adding the entry to >>> the rates dictionary BEFORE assigning its properties, then when the >>> properties are assigned, the hash code of "model" (key of the dictionary >>> entry) change and the Dictionary<,> implementation does not found it >>> anymore. >>> >>> At first, I thought that I had wrong implementations of >>> Equals/GetHashCode, but the strange thing is that if I don't fetch the rates >>> dictionary keys in the query, it works ok (although they are lazy-loaded): >>> >>> from Scheme e left join fetch e.Rates r where e.Name = 'something' >>> >>> My implementation of Equals and GetHashCode in each class is like this: >>> >>> public override bool Equals(object obj) >>> { >>> var other = obj as Model; >>> >>> if (other == null) >>> return false; >>> >>> bool otherIsTransient = other.ID == 0; >>> bool thisIsTransient = ID == 0; >>> if (otherIsTransient && thisIsTransient) >>> return ReferenceEquals(other, this); >>> >>> return other.ID.Equals(ID); >>> } >>> >>> public override int GetHashCode() >>> { >>> return (GetType().FullName + "|" + (Name ?? "*")).GetHashCode(); >>> } >>> >>> Am I doing something wrong here or there is a problem somewhere else? >>> (I've put together a test solution in case that someone would like to >>> take a look) >>> >>> >>> >> >> >> > > > -- > Fabio Maulo > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nhusers?hl=en -~----------~----~----~----~------~----~------~--~---
