OR演算子をクエリに組み込んで、テーブルの1つのフィールドと、結合されたテーブルの別のフィールドで特定の値を検索する方法を探しています。これはSQLではかなり基本的なことですが、NHibernateでこれを行う方法を世界が理解することはできません。私はWebを検索してきましたが、見つけた例は私にはかなり曖昧であり、特定の実装に適用するのは難しいと思います。
私はPartyというクラスを持っており、メインの参照であるreferenceという文字列フィールドがあります。新しい要件では、パーティーに多くのサイドリファレンスを追加できるオプションも必要でした。そのため、Partyと多対1の関係を持つPartyReferenceという別のクラスを追加する必要がありました。
ここで、指定された参照を使用して、このメイン参照フィールドとサイド参照の両方でその値を調べる必要があります。しかし、このフィールドが値または他のいずれかに対応している必要があることをNHibernateに伝えることができない限り、それを機能させることはできません。
私はこのような回避策を作成しましたが、「OR」と言う方法がなければならないため、エレガントで愚かです。
public Party GetPartyOnAnyReference(string reference)
{
Party party;
ISession session = Factory.OpenSession();
ITransaction tx = session.BeginTransaction();
try
{
//first search on main reference
ICriteria criteria1 = session.CreateCriteria(typeof(Party));
criteria1.Add(Restrictions.Eq("Reference", reference));
IList<Party> parties1 = criteria1.List<Party>();
party = parties1.Count > 0 ? parties1[0] : null;
//then try with side-references
if (party == null)
{
ICriteria criteria2 = session.CreateCriteria(typeof(Party));
criteria2
.SetFetchMode("References", FetchMode.Eager)
.CreateCriteria("References")
.Add(Expression.Eq("Reference", reference));
IList<Party> parties2 = criteria2.List<Party>();
party = parties2.Count > 0 ? parties2[0] : null;
}
session.Close();
}
catch (Exception e)
{
tx.Rollback();
session.Close();
if (e.GetType().ToString() == "NHibernate.ObjectNotFoundException")
party = null;
else throw;
}
return party;
}
もちろん、Partyクラスからメインの参照をすべて削除し、他の参照と同等にPartyReferenceとして扱うことで、この問題を解決できることも理解しています。しかし、ある段階で、とにかくNHibernateでORクエリを使用する必要があるので、この特定のケースで今すぐ解決することもできます。
何か案は?