It will assign the ID first, I think On Sat, Feb 21, 2009 at 3:41 PM, Germán Schuager <[email protected]>wrote:
> 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 -~----------~----~----~----~------~----~------~--~---
