Невозможно сравнить строки во время nHibernate QueryOver <T> - PullRequest
6 голосов
/ 16 июля 2011

У меня есть простой метод для проверки пользователей при входе в систему, и я использую Fluent nHibernate для постоянства, поэтому я естественным образом реализую ISession.QueryOver<T> для этой работы.

Это выглядит следующим образом.

var member = session.QueryOver<Member>()
   .Where(m => m.Email == Model.Email)
   .Take(1).SingleOrDefault();

Ok. Итак, проблемы под рукой.

  1. Адреса электронной почты всегда нужно сравнивать без учета регистра.

Они должны всегда находиться в базе данных как строчные. Я сделал все возможное, чтобы это произошло. На самом деле, мой <input>, принимающий Email Address, имеет правило проверки, разрешающее только строчные буквы. Но это все еще не достаточно хорошо, я хочу сделать это еще глубже и сделать абсолютно уверенным, что все кошерно.

Итак, я попытался сделать это ...

var member = session.QueryOver<Member>()
   .Where(m => String.Compare
         (m.Email, Model.Email, StringComparison.OrdinalIgnoreCase) == 0)
   .Take(1).SingleOrDefault();

Я получаю исключение, что nhibernate не может использовать метод String.Compare.

Я понимаю, что могу решить эту проблему с помощью простого метода ToLower(), но могут быть ситуации, когда мне нужно немного больше детализации по сравнению с другими видами сравнений.

Может кто-нибудь помочь мне разобраться, как это обойти?

Ответы [ 3 ]

3 голосов
/ 17 июля 2011

Есть несколько способов сделать это с IsInsensitiveLike:

   var member= Session.QueryOver<Member>()
       .WhereRestrictionOn(m=>m.Email).IsInsensitiveLike(Model.Email)
       .Take(1).SingleOrDefault();
2 голосов
/ 14 июля 2015

Если ответ @ VahidN об использовании сопоставления по умолчанию и / или с указанием явного не работает, можно перейти к преобразованию прецедента, специфичному для SQL-диалекта, например:

return _session.QueryOver<Registration>()
        .WhereEqualsIgnoreCase(r => r.Name, userName)   
        .Future().SingleOrDefault();

Реализовано следующим образом:

static class NHibernateCaseInsensitiveWhereExtensions
{
    public static IQueryOver<T, T2> WhereEqualsIgnoreCase<T, T2>(this IQueryOver<T, T2> that, Expression<Func<T, object>> column, string value)
    {
        return
            that.Where(
                Restrictions.Eq(
                    Projections.SqlFunction(
                        "upper", 
                        NHibernateUtil.String,
                        Projections.Property(column)),
                    value.ToUpper()));
    }
}
1 голос
/ 17 июля 2011

Соответствие текста в SQL Server НЕДОПУСТИМО. Если вам это не нравится, вы должны изменить сопоставление ( SQL_Latin1_General_CP1_CS_AS ) Поэтому вам не нужно ничего менять (на стороне сервера или на стороне клиента).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...