NHibernate de consulta de varias tablas
-
01-10-2019 - |
Pregunta
Estoy utilizando NHibernate, y estoy tratando de encontrar la manera de escribir una consulta, que searchs todos los nombres de mis entidades, y las listas de los resultados. Como un simple ejemplo, tengo los siguientes objetos;
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, que todos los retornos y los dueños de mascotas con un nombre que contiene "Ted", o los animales domésticos con un nombre que contiene "Ted".
Este es un ejemplo del 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 ( "gato") generan una o en lugar de la Y?
gracias por su ayuda.
Solución
Prueba de esto, que 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))
);
Otros consejos
Es necesario combinar los dos criterios que utilizan Expression.Or (criterios1, Criteria2)
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 que quería O todo. En ese caso, la adición de estos criterios a la disyunción, como se mostró BuggyDigger, es probablemente el camino a seguir.