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