複合 ID が使用されているエンティティがあります。複合 ID を別のキー クラスでラップするコードに変更しました。Linq を使用すると、キー オブジェクトを比較し、Criteria API を使用して Restrictions.IdEq を使用できると思っていましたが、どちらも失敗しました。キー値を明示的に比較して機能させる必要があります。
これが機能するかどうかのドキュメントが見つからないため、現時点では直接比較に固執していますが、これは、キーを変更するときにクエリコードも更新する必要があることを意味しますが、これは明らかに私が望むものではありません。
補足として、NHibernate 3.0.0 Alpha 2 および 3 でこれを試しました。
ドメイン
マッピング
<?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>
クラス
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;
}
}
}
ワーキングクエリ
以下のクエリは機能し、ご覧のとおり、キー値を明示的に比較しています。キーオブジェクトは比較しません。
リンク
from status
in session.Query<AddonStatus>()
where status.Id.Context == context && status.Id.AddonType == addonType
select status
基準 API
session.CreateCriteria<AddonStatus>()
.Add(Restrictions.Eq("Id.Context", context))
.Add(Restrictions.Eq("Id.AddonType", addonType))
動作することが期待されますが、動作しません
次のクエリが機能することを期待しています。データベースの代わりにメモリ内のlinqで効率的に実行できますが、クエリでそのような複合IDを処理するのに十分なほど賢く、基準APIが期待されます。
linq と criteria api クエリはどちらも Key オブジェクトの比較を利用します。
var key = new AddonStatus.Key
{
Context = context,
AddonType = addonType
};
リンク
from status
in session.Query<AddonStatus>()
where status.Id == key
select status
基準 API
session.CreateCriteria<AddonStatus>()
.Add(Restrictions.IdEq(key))
誰かがそのようなシナリオが機能している場合、私は何が間違っているのでしょうか?