Нечеткий поиск по объединенному полному имени с помощью NHibernate - PullRequest
5 голосов
/ 15 июля 2011

Я пытаюсь преобразовать следующий SQL в NHibernate:

SELECT * FROM dbo.Customer
WHERE FirstName + ' ' + LastName LIKE '%' + 'bob smith' + '%'

Я пытался сделать что-то подобное, но это не работает:

name = "%" + name + "%";

var customers = _session.QueryOver<Customer>()
            .Where(NHibernate.Criterion.Restrictions.On<Customer>(c => c.FirstName + ' ' + c.LastName).IsLike(name))
            .List();

Что я в основном пытаюсь сделать, так это уметь искать имя клиента в текстовом поле с примером значения «bob smith» и искать его в базе данных, используя выражение LIKE в SQL выше.

Если я собираюсь выполнить неправильный поиск в столбцах FirstName и LastName, пожалуйста, помогите мне с альтернативой, но приведенный выше SQL-запрос даст мне то, что мне нужно.

Обновление с 2 решениями:

Итак, я нашел два решения этой проблемы. Одним из них является использование Criteria API. Следующий пост имеет ответ, который прекрасно работает: https://stackoverflow.com/a/2937100/670028

Другое решение я нашел благодаря одному из моих коллег, который предложил использовать проекцию LINQ и анонимные типы. Вот решение с использованием LINQ:

var customers = session.Query<Customer>()
    .Select( x => new { FullName = x.FirstName + " " + x.LastName, Customer = x } )
    .Where( x => x.FullName.Contains( "Bob Smith" ) )
    .Select( x => x.Customer )
    .ToList();

Ответы [ 4 ]

10 голосов
/ 15 июля 2011

NHibernate не может перевести выражение в оператор SQL, потому что не знает, что делать с c => c.FirstName + '' + c.LastName.Решением может быть переписывание этого примерно так:

Session.CreateCriteria<Customer>()
    .Add(Restrictions.Like(
    Projections.SqlFunction("concat",
                            NHibernateUtil.String,
                            Projections.Property("FirstName"),
                            Projections.Constant(" "),
                            Projections.Property("LastName")),
    "Bob Whiley",
    MatchMode.Anywhere))
1 голос
/ 20 февраля 2013

Если вы хотите, чтобы ваш код был максимально строгим, вот то, как я этого добился. Мне нужно было использовать его в дизъюнкции. Надеюсь, это кому-нибудь поможет!

var disjunction = new Disjunction();
var fullNameProjection = Projections.SqlFunction(
    "concat",
    NHibernateUtil.String,
    Projections.Property<UserProfile>(x => x.FirstName),
    Projections.Constant(" "),
    Projections.Property<UserProfile>(x => x.LastName)
    );
var fullNameRestriction = Restrictions.Like(fullNameProjection, searchText, MatchMode.Anywhere);
disjunction.Add(fullNameRestriction);
0 голосов
/ 15 июля 2011

Я могу попробовать это:

query.Where(Restrictions.On<MyType>(x => x.Field).IsLike(StringToSearch))

Если это слишком сложно с QueryOver или Criteria API, вы можете использовать синтаксис HQL

0 голосов
/ 15 июля 2011

Я думаю, что это будет примерно так:

.On (c => c.IsLike (c.FirstName + '' + c.LastName))

Потому что вы не 't сравнивая правильные значения так, как вы это делаете прямо сейчас.

...