2010-09-13 18 views
1

我正在寻找一种方法在查询中构建OR运算符,以在表的一个字段以及另一个字段中查找特定值。这在SQL中是非常基本的,但我不能让全世界知道如何在NHibernate中做到这一点。我一直在寻找网络,但我发现的例子对我来说很模糊,我发现它们很难适用于我的特定实现。NHibernate:使用OR运算符查询

我有一个名为Party的类,其中有一个名为reference的字符串字段,它是主要的参考。新的要求要求选项也能够增加很多侧面引用到一方。所以我不得不添加一个名为PartyReference的类,它与Party有多对一的关系。

现在有了一个给定的参考文献,我必须在这个主参考字段以及副参考文献中查看它的值。但只要我不知道对NHibernate说,这个字段必须与其他值相对应,我不能使它工作。

我做了一个变通方法,看起来是这样,但是这是不好的和愚蠢的,因为必须有办法说“或”:

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; 
     } 

当然我知道我也可以解决这个问题通过简单地将党的主要参考文献全部删除,并将其与其他参考文献相提并论,作为党参考。但是在某个阶段,我将不得不对NHibernate使用OR查询,所以我现在可以用这个特例来解决它。

任何想法?

回答

4

您可以使用Restrictions.Or或对多个或多个使用分隔符。

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>(); 
+0

非常感谢!这正是我期待的优雅解决方案。我不得不多次运行单元测试来相信自己的眼睛。 – 2010-09-13 20:41:07

+0

只需稍作更改:“LeftOuterJoin”为“JoinType.LeftOuterJoin”... – 2010-09-13 20:55:16