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