2010-09-13 62 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