views:

33

answers:

0

I have an entity where a composite id is used. I changed to code to make use of wrapping the composite id in a seperate key class. I expected that with Linq I could do a comparison on key object and with the Criteria API to use Restrictions.IdEq but both fail. I need to explicitly compare the key values to make it work.

I cannot find any documentation if this should work so for the moment I am stuck with direct comparisons but this means that when I alter the key that I also need to update the query code which is obviously not what I would want.

As a side note, I tried this with NHibernate 3.0.0 Alpha 2 and 3.

Domain

Mapping

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Cwc.Pulse.Dal"
                   namespace="Cwc.Pulse.Dal">
  <class name="AddonStatus">
    <composite-id name="Id">
      <key-many-to-one name="Context" column="Context_Id" class="Context" />
      <key-property name="AddonType" column="Addon_Id"/>
    </composite-id>
    <property name="Status" />
  </class>
</hibernate-mapping>

Class

public class AddonStatus
{
    public virtual string Status { get; set; }
    public virtual Key Id { get; protected set; }

    public AddonStatus()
    {
        Id = new Key();
    }

    public class Key
    {
        public virtual Context Context { get; set; }
        public virtual AddonType AddonType { get; set; }

        public override int GetHashCode()
        {
            return ContextId.GetHashCode() ^ AddonType.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (this == obj) return true;
            var o = obj as Key;
            if (null == o) return false;
            return Context == o.Context && AddonType == o.AddonType;
        }
    }
}

Working queries

The queries below work and as you can see I compare the key values explicitly. I do not compare the key object.

Linq

from status
in session.Query<AddonStatus>()
where status.Id.Context == context && status.Id.AddonType == addonType
select status

Criteria API

session.CreateCriteria<AddonStatus>()
.Add(Restrictions.Eq("Id.Context", context))
.Add(Restrictions.Eq("Id.AddonType", addonType))

Expected to work but dont

I expect the following queries to work. Either in efficiently for linq in memory instead of the database but I expect the criteria api to be smart enough to handle such composite id´s in queries.

Both linq and criteria api queries make use of a Key object comparison.

var key = new AddonStatus.Key
{
    Context = context,
    AddonType = addonType
};

Linq

from status
in session.Query<AddonStatus>()
where status.Id == key
select status

Criteria API

session.CreateCriteria<AddonStatus>()
.Add(Restrictions.IdEq(key))

So if anyone has such a scenario working then what am I doing wrong?