NHibernate: запрос с оператором ИЛИ - PullRequest
1 голос
/ 13 сентября 2010

Я ищу способ встроить оператор 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;
       }

Я, конечно, понимаю, что могу также решить эту проблему, просто полностью удалив основную ссылку из класса партии и рассматривая ее наравне с другими ссылками, как ссылку на ссылку. Но на каком-то этапе мне все равно придется использовать запрос OR с NHibernate, так что теперь я мог бы решить его именно в этом конкретном случае.

Есть идеи?

1 Ответ

4 голосов
/ 13 сентября 2010

Вы можете использовать Restrictions.Or или Disjunction для нескольких или.

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>();
...