2010-05-29 5 views
3

J'avais besoin de filtrer une liste de résultats en utilisant la combinaison de deux propriétés. Une instruction SQL simple ressemblerait à ceci:Critères NHibernate - Comment filtrer sur une combinaison de propriétés

SELECT TOP 10 * 
FROM Person 
WHERE FirstName + ' ' + LastName LIKE '%' + @Term + '%' 

Le ICriteria dans NHibernate que je fini par utiliser est:

ICriteria criteria = Session.CreateCriteria(typeof(Person)); 
criteria.Add(Expression.Sql(
    "FirstName + ' ' + LastName LIKE ?", 
    "%" + term + "%", 
    NHibernateUtil.String)); 
criteria.SetMaxResults(10); 

Il fonctionne parfaitement, mais je ne suis pas sûr que ce soit la solution idéale puisque je suis encore en train d'apprendre sur l'API Criteria de NHibernate. Quelles sont les alternatives recommandées?

  • Existe-t-il autre chose que Expression.Sql qui effectuerait la même opération? J'ai essayé Expression.Like mais n'a pas pu comprendre comment combiner le prénom et le nom.
  • Dois-je mapper une propriété FullName à la formule "FirstName + '' + Nom" dans la classe de mappage?
  • Dois-je créer une propriété FullName en lecture seule sur l'objet de domaine puis la mapper sur une colonne?

Répondre

13

vous pouvez faire une des opérations suivantes:

  • Si vous travaillez toujours avec le nom complet, il est probablement préférable d'avoir une seule propriété
  • Créer une propriété de requête uniquement à cette fin (voir http://ayende.com/Blog/archive/2009/06/10/nhibernate-ndash-query-only-properties.aspx)
  • Est-ce que la requête dans HQL, ce qui est mieux adapté pour les requêtes de forme libre (il sera probablement à peu près le même que votre SQL)
  • Utilisez un Critères à base d'entité:-appropriés

Session.CreateCriteria<Person>() 
     .Add(Restrictions.Like(
      Projections.SqlFunction("concat", 
            NHibernateUtil.String, 
            Projections.Property("FirstName"), 
            Projections.Constant(" "), 
            Projections.Property("LastName")), 
      term, 
      MatchMode.Anywhere)) 
+0

Query-only - comment très utile, ne savait pas à propos de cette option. On dirait que j'apprends quelque chose de nouveau tous les jours dans NHibernate. Merci pour l'exemple de code Projections aussi. – DavGarcia

0

Sur le plan technique pur je n'ai pas une réponse, mais considérez ceci: puisque vous avez seulement un seul champ d'entrée pour l'utilisateur d'entrer le terme, vous ne savez pas s'il va pour entrer dans « foo bar » ou « bar foo » ... donc je recommande ceci:

ICriteria criteria = Session.CreateCriteria(typeof(Person)); 
criteria.Add(Expression.Like("FirstName",term, MatchMode.Anywhere) || Expression.Like("LastName",term, MatchMode.Anywhere)); 
criteria.SetMaxResults(10); 
+0

Merci pour les suggestions. A l'origine, j'ai essayé mais les gens tapaient "john smi" et s'attendaient à voir apparaître John Smith. – DavGarcia

+0

Je m'occupe de ce cas en regardant s'il n'y a pas d'espace correspondant à la première ou à la dernière place s'il y a un espace, puis je divise la chaîne de recherche et recherche à nouveau contre le premier et le dernier. – JoshBerke

Questions connexes