2010-04-22 13 views
8

Estoy usando NHibernate, y estoy tratando de averiguar cómo escribir una consulta, que busca todos los nombres de mis entidades, y enumera los resultados. Como un simple ejemplo, tengo los siguientes objetos;NHibernate Consulta en múltiples tablas

public class Cat { 
public string name {get; set;} 
} 

public class Dog { 
    public string name {get; set;} 
} 

public class Owner { 
    public string firstname {get; set;} 
    public string lastname {get; set;} 
} 

eventaully Quiero crear una consulta, digamos por ejemplo, cuáles y devuelve todos los dueños de mascotas con un nombre que contiene "Ted", o animales con un nombre que contiene "Ted".

Aquí es un ejemplo de SQL Quiero ejecutar:

SELECT TOP 10 d.*, c.*, o.* FROM owners AS o 
INNER JOIN dogs AS d ON o.id = d.ownerId 
INNER JOIN cats AS c ON o.id = c.ownerId 
WHERE o.lastname like '%ted%' 
OR o.firstname like '%ted%' 
OR c.name like '%ted%' 
OR d.name like '%ted%' 

Cuando lo hago utilizando criterios como esto:

var criteria = session.CreateCriteria<Owner>() 
     .Add(
     Restrictions.Disjunction() 
      .Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere)) 
      .Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere)) 
     ) 
     .CreateCriteria("Dog").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere)) 
     .CreateCriteria("Cat").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere)); 
     return criteria.List<Owner>(); 

Se genera la siguiente consulta:

SELECT TOP 10 d.*, c.*, o.* FROM owners AS o 
    INNER JOIN dogs AS d ON o.id = d.ownerId 
    INNER JOIN cats AS c ON o.id = c.ownerId 
    WHERE o.lastname like '%ted%' 
    OR o.firstname like '%ted%' 
    AND d.name like '%ted%' 
    AND c.name like '%ted%' 

¿Cómo puedo ajustar mi consulta para que el .CreateCriteria ("Perro") y .CreateCriteria ("Cat") generen un OR en lugar de t él Y?

gracias por su ayuda.

Respuesta

5

Prueba esto, podría funcionar.

var criteria = session.CreateCriteria<Owner>() 
      .CreateAlias("Dog", "d") 
      .CreateAlias("Cat", "c") 
      .Add(
      Restrictions.Disjunction() 
       .Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere)) 
       .Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere)) 
       .Add(Restrictions.Like("c.Name", keyword, MatchMode.Anywhere)) 
       .Add(Restrictions.Like("d.Name", keyword, MatchMode.Anywhere)) 
      ); 
+0

Gracias, eso pareció hacerlo. Encontré una publicación aquí: http://mattthr.blogspot.com/2010/02/quey-across-join-in-nhibernate.html e iba a intentarlo –

2

es necesario combinar los dos criterios que utilizan Expression.Or (criterios1, Criteria2)

Más aquí: http://devlicio.us/blogs/derik_whittaker/archive/2009/04/21/creating-a-nested-or-statement-with-nhibernate-using-the-criteria-convention.aspx

Hmm creo que sería el siguiente (tomado un poco de código de BuggyDigger)

var criteria = session.CreateCriteria<Owner>() 
    .CreateAlias("Dog", "d") 
    .CreateAlias("Cat", "c") 
    .Add(Expression.Or(Expression.Like("c.Name", keyword, MatchMode.Anywhere) 
      , Expression.Like("d.Name", keyword, MatchMode.Anywhere)) 
     ); 

Pero no me di cuenta de que quería O todo. En ese caso, agregar estos criterios a la disyunción, como lo demostró BuggyDigger, es probablemente el camino a seguir.

+0

Gracias por responder Alex, podría dar un ejemplo. Intenté lo que hiciste, pero me aparece "no puedo convertir ICriteria en Icriterion" –

+0

Aclarado en mi publicación, pero como he leído la pregunta incorrectamente, puede que no importe;) – AlexCuse

+0

¡Gracias por tu ayuda de todos modos! Lo tengo funcionando perfectamente ahora! ;) –

Cuestiones relacionadas