I have an object that uses a composite identifier. I changed the code to use a composite id wrapper in a separate key class. I expected that with Linq, I could do a comparison on a key object, and using the criteria API use Restrictions.IdEq, but both do not work. I need to explicitly compare key values ββto make it work.
I canβt find any documentation if it works like this at the moment that I follow direct comparisons, but that means that when I change the key, I also need to update the request code, which is clearly not the one I would like .
As a side note, I tried this with NHibernate 3.0.0 Alpha 2 and 3.
Domain
Display
<?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; } } }
Work requests
The following are the queries, and as you can see, I am explicitly comparing the key values. 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))
It is expected that it will work, but not
I expect the following queries to work. It is either efficient for linq in memory instead of a database, but I expect the api criteria to be smart enough to handle such complex identifiers in queries.
Both linq queries and api criteria use Key object comparisons.
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 someone has such a scenario, then what am I doing wrong?