Question

Je cherche un moyen de construire un opérateur OR dans une requête pour rechercher une valeur particulière dans un domaine d'une table, ainsi que dans un autre domaine d'une table jointe. Ceci est assez basique dans SQL, mais je ne peux pas pour la figure monde comment faire en NHibernate. J'ai cherché sur le web, mais les exemples que je trouve sont assez nébuleux pour moi et je les trouve difficile à appliquer à ma mise en œuvre particulière.

J'ai une classe appelée Parti, avec une chaîne de champ appelé référence, qui est la principale référence. De nouvelles exigences ont demandé la possibilité d'être également en mesure d'ajouter beaucoup de références secondaires à une partie. Donc, je devais ajouter une autre classe appelée PartyReference qui a un grand nombre à une relation à la partie.

Maintenant, avec une référence donnée, je dois regarder sa valeur dans les deux ce champ principal de référence, ainsi que parmi les références secondaires. Mais tant que je ne peux pas comprendre à dire NHibernate que, soit ce champ doit correspondre à la valeur ou l'un des autres, je ne peux pas le faire fonctionner.

J'ai fait une solution de contournement qui ressemble à ceci, mais il est inélégant et stupide, car il doit y avoir moyen de dire « OU »:

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

Bien sûr, je me rends compte que je peux résoudre ce problème en supprimant tout simplement la référence principale de la alltogether de classe du Parti et de la traiter à égalité avec les autres références, comme PartyReference. Mais à un moment donné, je vais devoir utiliser une ou requête NHibernate de toute façon, donc je pourrais tout aussi bien le résoudre maintenant avec ce cas particulier.

Toutes les idées?

Était-ce utile?

La solution

Vous pouvez utiliser Restrictions.Or ou utiliser un Disjunction pour plusieurs ou de.

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>();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top