1

我正在寻找一种将 OR 运算符构建到查询中的方法,以在表的一个字段以及连接表的另一个字段中查找特定值。这在 SQL 中是非常基本的,但我无法为全世界弄清楚如何在 NHibernate 中做到这一点。我一直在网上搜索,但我发现的例子对我来说非常模糊,我发现它们很难应用于我的特定实现。

我有一个名为 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;
       }

我当然意识到我也可以通过简单地从 Party 类中删除主要引用并将其与其他引用同等对待,作为 PartyReference 来解决这个问题。但是在某个阶段,无论如何我都必须对 NHibernate 使用 OR 查询,所以我现在不妨用这个特殊情况来解决它。

有任何想法吗?

4

1 回答 1

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>();
于 2010-09-13T19:24:01.543 回答