Критерии NHibernate - Как фильтровать по комбинации свойств
Мне нужно было отфильтровать список результатов, используя комбинацию двух свойств. Простой SQL-оператор будет выглядеть так:
SELECT TOP 10 *
FROM Person
WHERE FirstName + ' ' + LastName LIKE '%' + @Term + '%'
ICriteria в NHibernate, который я в конечном итоге использовал:
ICriteria criteria = Session.CreateCriteria(typeof(Person));
criteria.Add(Expression.Sql(
"FirstName + ' ' + LastName LIKE ?",
"%" + term + "%",
NHibernateUtil.String));
criteria.SetMaxResults(10);
Это работает отлично, но я не уверен, что это идеальное решение, так как я все еще изучаю API Критерии NHibernate. Каковы рекомендуемые альтернативы?
- Есть ли что-то кроме
Expression.Sql
что бы выполнить ту же операцию? Я старалсяExpression.Like
но не мог понять, как объединить имя и фамилию. - Должен ли я сопоставить свойство FullName с формулой "FirstName + ' ' + LastName" в классе сопоставления?
- Должен ли я создать свойство FullName только для чтения для объекта домена, а затем сопоставить его со столбцом?
2 ответа
Решение
Вы можете сделать одно из следующего:
- Если вы всегда работаете с полным именем, лучше всего иметь одно свойство
- Для этого создайте свойство только для запроса (см. http://ayende.com/Blog/archive/2009/06/10/nhibernate-ndash-query-only-properties.aspx).
- Выполните запрос на HQL, который лучше подходит для запросов произвольной формы (вероятно, он будет почти таким же, как ваш SQL)
- Используйте надлежащие основанные на сущности критерии:
Session.CreateCriteria<Person>()
.Add(Restrictions.Like(
Projections.SqlFunction("concat",
NHibernateUtil.String,
Projections.Property("FirstName"),
Projections.Constant(" "),
Projections.Property("LastName")),
term,
MatchMode.Anywhere))
С чисто технической стороны у меня нет ответа, но учтите это: поскольку у вас есть только одно поле ввода для пользователя, чтобы ввести термин, вы не знаете, собирается ли он ввести 'foo bar' или 'bar foo'... поэтому я бы порекомендовал это:
ICriteria criteria = Session.CreateCriteria(typeof(Person));
criteria.Add(Expression.Like("FirstName",term, MatchMode.Anywhere) || Expression.Like("LastName",term, MatchMode.Anywhere));
criteria.SetMaxResults(10);