2010-09-07 4 views
3

J'ai cherché sur le web pendant plusieurs heures pour essayer d'obtenir une réponse à ce sujet, mais en vain. Ce que j'essaie de faire est la quantité de disjonctions AND 'N' pour affiner les recherches basées sur une requête délimitée par des espaces blancs.NHibernate AND'ing Disjunction dynamique

J'ai un 'Unity' qui peut être n'importe quelle combinaison d'une seule personne ou organisation ou plusieurs personnes/organisation, ou une combinaison de ce qui précède.

Donc, si je recherche 'Smith', je veux faire correspondre des entreprises OU des personnes avec le nom 'Smith', facile.

Cependant, si quelqu'un tapait 'Smith w' et voulait des correspondances sur les différents combos (OR sur Personne et Organisation).

Je recevrais un coup que pour une unité (combinaison de personnes et/ou organisations) qui a à la fois une entreprise ou d'une personne avec Smith soit une organisation

ICriteria query = Session.CreateCriteria(typeof(Unity), "u") 
       .CreateCriteria("Organisations", "o", JoinType.LeftOuterJoin) 
       .CreateCriteria("u.People", "p", JoinType.LeftOuterJoin) 
       .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
       .SetMaxResults(10); 

     Disjunction keywordsCriteria = Restrictions.Disjunction(); 

     if (searchTerms.Contains(' ')) { 
      foreach (var keyword in searchTerms.Split(' ')) { 
       var term = string.Format("%{0}%", keyword); 
       keywordsCriteria 
        .Add(Restrictions.Like("p.FirstName", term)) 
        .Add(Restrictions.Like("p.LastName", term)) 
        .Add(Restrictions.Like("o.Name", term)); 
      } 

     } 
     else 
     { 
      var term = string.Format("%{0}%", searchTerms); 
      keywordsCriteria 
       .Add(Restrictions.Like("p.FirstName", term)) 
       .Add(Restrictions.Like("p.LastName", term)) 
       .Add(Restrictions.Like("o.Name", term)); 
     } 
     query.Add(keywordsCriteria); 

     return query.List<Unity>(); 

Il en résulte

where(p2_.Name1 like '%smith%' /* @p0 */ 
    or p2_.Name3 like '%smith%' /* @p1 */ 
    or o1_.EntityName like '%smith%' /* @p2 */ 
    or p2_.Name1 like '%w%' /* @p3 */ 
    or p2_.Name3 like '%w%' /* @p4 */ 
    or o1_.EntityName like '%w%' /* @p5 */) 

Cependant ce que je veux produire est le dessous

WHERE ((p2_.Name1 like '%smith%' /* @p0 */ 
    or p2_.Name3 like '%smith%' /* @p1 */ 
    or o1_.EntityName like '%smith%' /* @p2 */) 
    AND(
    p2_.Name1 like '%w%' /* @p3 */ 
    or p2_.Name3 like '%w%' /* @p4 */ 
    or o1_.EntityName like '%w%' /* @p5 */)) 

Répondre

2

utilisent ce

if (!searchTerms.Contains(' ')) 
{ 
    Disjunction keywordsCriteria = Restrictions.Disjunction(); 
    var term = string.Format("%{0}%", searchTerms); 
    keywordsCriteria 
     .Add(Restrictions.Like("p.FirstName", term)) 
     .Add(Restrictions.Like("p.LastName", term)) 
     .Add(Restrictions.Like("o.Name", term)); 
    query.Add(keywordsCriteria); 
} 
else 
{ 
    Conjunction conjunction = Restrictions.Conjunction(); 
    foreach (var keyword in searchTerms.Split(' ')) 
    { 
     Disjunction disjunction = Restrictions.Disjunction(); 
     var term = string.Format("%{0}%", keyword); 
      disjunction 
      .Add(Restrictions.Like("p.FirstName", term)) 
      .Add(Restrictions.Like("p.LastName", term)) 
      .Add(Restrictions.Like("o.Name", term)); 
     conjunction.Add(disjunction); 
    } 
    query.Add(conjunction); 
} 
+0

Ah! Si proche mais si loin! Merci beaucoup! –

1

Merci pour la réponse, fonctionne un charme, juste a dû changer un petit peu, je devais créer une nouvelle Disjunction pour chaque boucle ou il garderait se joint à.

Je n'arrive pas à croire que je n'ai pas compris ça!

if (searchTerms.Contains(' ')) { 
      foreach (var keyword in searchTerms.Split(' ')) { 
       var term = string.Format("%{0}%", keyword); 
       Disjunction keywordsCriteria = Restrictions.Disjunction(); // <<-- 
       keywordsCriteria 
        .Add(Restrictions.Like("p.FirstName", term)) 
        .Add(Restrictions.Like("p.LastName", term)) 
        .Add(Restrictions.Like("o.Name", term)); 
       query.Add(keywordsCriteria); 
      } 
     } 
     else 
     { 
      var term = string.Format("%{0}%", searchTerms); 
      Disjunction keywordsCriteria = Restrictions.Disjunction(); // <<-- 
      keywordsCriteria 
       .Add(Restrictions.Like("p.FirstName", term)) 
       .Add(Restrictions.Like("p.LastName", term)) 
       .Add(Restrictions.Like("o.Name", term)); 
      query.Add(keywordsCriteria); 
     } 
+0

lol oui en effet :) – Jaguar