NHibernate requêtes sur plusieurs tables
-
01-10-2019 - |
Question
J'utilise NHibernate, et essaie de comprendre comment écrire une requête, que tous les noms searchs de mes entités, et énumère les résultats. A titre d'exemple simple, j'ai les objets suivants:
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 Je veux créer une requête, disons par exemple, qui et retourne tous les propriétaires d'animaux avec un nom contenant « ted », ou des animaux avec un nom contenant « ted ».
Voici un exemple de SQL que je veux exécuter:
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%'
Quand je le fais en utilisant des critères comme ceci:
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>();
La requête suivante est générée:
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%'
Comment puis-je régler ma requête afin que la générer un OU au lieu de ET? .CreateCriteria ( « chien ») et .CreateCriteria ( « chat »)
Merci pour votre aide.
La solution
Essayez cela, il pourrait fonctionner.
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))
);
Autres conseils
Vous devez combiner les deux critères à l'aide Expression.Or (Criteria1, critères2)
Plus d'informations ici: http://devlicio.us/blogs/derik_whittaker/archive/2009/04/21/creating-a-nested-or-statement-with-nhibernate-using-the- critères convention.aspx
Hmm je pense qu'il ressemblerait à ceci (emprunté un peu de code 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))
);
Mais je ne l'ai pas remarqué que vous vouliez OU tout. Dans ce cas, l'ajout de ces critères à la disjonction, comme BuggyDigger a montré, est probablement la voie à suivre.