Criterios de NHibernate - Cómo filtrar en combinación de propiedades
-
05-10-2019 - |
Pregunta
I necesarios para filtrar una lista de resultados utilizando la combinación de dos propiedades. Una sentencia SQL sencilla sería el siguiente:
SELECT TOP 10 *
FROM Person
WHERE FirstName + ' ' + LastName LIKE '%' + @Term + '%'
El ICriteria en NHibernate que terminó usando era:
ICriteria criteria = Session.CreateCriteria(typeof(Person));
criteria.Add(Expression.Sql(
"FirstName + ' ' + LastName LIKE ?",
"%" + term + "%",
NHibernateUtil.String));
criteria.SetMaxResults(10);
Funciona perfectamente, pero no estoy seguro si es la solución ideal, ya que todavía estoy aprendiendo sobre el API Criterios de NHibernate. ¿Cuáles son las alternativas recomendadas?
- ¿Hay algo más que
Expression.Sql
que realizar la misma operación? ProbéExpression.Like
pero no podía encontrar la manera de combinar los nombres y apellidos. - ¿Debo asignar una propiedad FullName a la fórmula "Nombre + '' + Apellido" en la clase de mapeo?
- ¿Debo crear una propiedad de sólo lectura NombreCompleto en el objeto de dominio a continuación, asignar a una columna?
Solución
Se puede hacer una de las siguientes:
- Si siempre trabajo con el nombre completo, probablemente es mejor tener una sola propiedad
- Crear una propiedad de sólo consulta para ese fin (véase http://ayende.com/Blog/archive/2009/06/10/nhibernate-ndash-query-only-properties.aspx )
- Haga la consulta en HQL, lo que es más adecuado para las consultas de forma libre (que probablemente será casi lo mismo que su SQL)
- Usar una adecuados criterios basados ??en la entidad:
Session.CreateCriteria<Person>()
.Add(Restrictions.Like(
Projections.SqlFunction("concat",
NHibernateUtil.String,
Projections.Property("FirstName"),
Projections.Constant(" "),
Projections.Property("LastName")),
term,
MatchMode.Anywhere))
Otros consejos
En el aspecto técnico puro no tengo una respuesta, pero considera esto: Ya que sólo tiene un solo campo de entrada para que el usuario introduzca el término, no sabe si va a entrar 'foo bar' o 'foo bar' ... así que recomiendo esto:
ICriteria criteria = Session.CreateCriteria(typeof(Person));
criteria.Add(Expression.Like("FirstName",term, MatchMode.Anywhere) || Expression.Like("LastName",term, MatchMode.Anywhere));
criteria.SetMaxResults(10);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow