Поддерживает ли NHibernate LINQ предложения ToLower() в Where()?

У меня есть сущность и ее отображение:

public class Test
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
}

public class TestMap : EntityMap<Test>
{
    public TestMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.Description);
    }
}

Я пытаюсь запустить запрос на него (чтобы извлечь его из базы данных):

var keyword = "test" // this is coming in from the user
keyword = keyword.ToLower(); // convert it to all lower-case

var results = session.Linq<Test>
    .Where(x => x.Name.ToLower().Contains(keyword));

results.Count(); // execute the query

Однако всякий раз, когда я запускаю этот запрос, я получаю следующее исключение:

Index was out of range. Must be non-negative and less than the size of the
collection. Parameter name: index

Я прав, когда я говорю, что в настоящее время Linq для NHibernate не поддерживает ToLower()? И если да, есть ли альтернатива, которая позволяет мне искать строку в середине другой строки, с которой Linq to NHibernate совместим? Например, если пользователь ищет kap, мне нужно, чтобы он соответствовал Kapiolani, Makapuu и Lapkap.

Ответы

Ответ 1

У меня это случилось недавно. Я могу сказать вам, что ToLower() не работает и что Contains() и StartsWith() работают и не чувствительны к регистру. Вы можете получить желаемое влияние, используя напрямую Contains() и StartsWith().

Ответ 2

Кажется, что существует много путаницы в этом вопросе.

  • "Старый" поставщик Linq (для NHibernate 2.x), вероятно, может не поддерживать это. Если это произойдет, это никогда не будет, потому что оно больше не поддерживается.
  • Новый провайдер (включенный в NHibernate 3.x) поддерживает (хотя ToUpper и ToLower, похоже, инвертированы, см. http://groups.google.com/group/nhibernate-development/browse_thread/thread/a167216e466b3241)
  • Contains и StartsWith отображаются в операторе LIKE в SQL. Они не нечувствительны к регистру сами; это сопоставление, которое делает их нечувствительными к регистру, поэтому это зависит от того, как была создана ваша колонка/схема.

Обновление (2010-04-09): ошибка подтверждена и исправлена, см. https://nhibernate.jira.com/browse/NH-2169

Update (2010-05-21): patch был применен в 2010-05-01 и работает как ожидается.

Ответ 4

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

Если это не так, то вам не нужно .ToLower()

Ответ 5

В принятом ответе упоминаются хорошие Contains() и StartsWith(). но не работает в тех случаях, когда вы хотите убедиться, что обе строки одинаковы.

Достаточно будет использовать "==", так как он также не учитывает регистр. Таким образом, вам больше не нужно использовать ToLower() или ToUpper();