我正在寻找一种方法来在查询中构建OR运算符,以在表的一个字段以及连接表的另一个字段中查找特定值。这在SQL中非常基础,但我不能让全世界想出如何在NHibernate中做到这一点。我一直在网上搜索,但我发现的例子对我来说非常模糊,我发现它们难以适用于我的特定实现。
我有一个叫做Party的类,有一个名为reference的字符串字段,它是主要的引用。新要求要求还可以为一方添加大量的侧面参考。所以我不得不添加另一个名为PartyReference的类,它与Party有很多关系。
现在有了一个给定的引用,我必须在这个主引用字段以及副引用中查看它的值。但是,只要我不知道对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查询,所以我现在也可以用这个特殊情况解决它。
有什么想法吗?
答案 0 :(得分:4)
您可以使用Restrictions.Or
或使用Disjunction for multiple或's。
session.CreateCriteria<Party>()
.CreateAlias("References", "r", JoinType.LeftOuterJoin)
.Add(Restrictions.Or(
Restrictions.Eq("Reference", reference),
Restrictions.Eq("r.Reference", reference)))
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<Party>();