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
-~----------~----~----~----~------~----~------~--~---

Reply via email to