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)

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