Linq to Entities: использование ToLower () в полях NText - PullRequest
13 голосов
/ 12 марта 2010

Я использую SQL Server 2005 с чувствительной к регистру базой данных.

В функции поиска мне нужно создать запрос Linq To Entities (L2E) с предложением «where», которое сравнивает несколько строк с данными в базе данных по следующим правилам:

  1. Сравнение - это режим "Содержит", а не строгое сравнение: просто, поскольку в L2E разрешен метод Contains () строки *
  2. Сравнение должно быть без учета регистра: я использую ToLower () для обоих элементов, чтобы выполнить нечувствительное сравнение.

Все это работает очень хорошо, но я столкнулся со следующим исключением: «Аргумент типа данных ntext недопустим для аргумента 1 нижней функции» в одном из моих полей.

Кажется, что это поле NText, и я не могу выполнить ToLower () для этого.
Что я могу сделать, чтобы иметь возможность выполнять регистр () без учета регистра в этом поле NText?

Ответы [ 3 ]

29 голосов
/ 12 марта 2010

Никогда не используйте .ToLower() для сравнения без учета регистра. И вот почему:

  1. Возможно, это неправильно (ваша сортировка клиента может быть, скажем, турецкой, а ваша сортировка БД - нет).
  2. Это очень неэффективно; Излучаемый SQL равен LOWER вместо = с сортировкой без учета регистра.

Вместо этого используйте StringComparison.OrdinalIgnoreCase или StringComparison.CurrentCultureIgnoreCase:

var q = from f in Context.Foos
        where f.Bar.Equals("hi", StringComparison.OrdinalIgnoreCase)
        select f;

Но для Contains() есть проблема: в отличие от Equals, StartsWith и т. Д., Он не перегружен для аргумента StringComparison. Зачем? Хороший вопрос; спросите у Microsoft.

Это в сочетании с ограничением SQL Server для LOWER означает, что не существует простого способа сделать то, что вы хотите.

Возможные обходные пути:

  • Используйте полнотекстовый индекс и выполните поиск в процедуре.
  • Используйте Equals или StartsWith вместо этого, если это возможно для вашей задачи
  • Изменить параметры сортировки по умолчанию для столбца?
5 голосов
/ 10 октября 2012

Используйте здесь лямбда-выражение и создайте промежуточный список, который может обрабатывать нижнее предложение.

var q = Context.Foos.ToList().Where(s => s.Bar.ToLower().Contains("hi"));

Не очень эффективно, но работает. Если у вас есть дополнительные предикаты в предложении where, это работает в ваших интересах:

var q = Context.Foos.Where(p => p.f1 == "foo" && p.f2 == "bar").
            ToList().Where(s => s.Bar.ToLower().Contains("hi"));
0 голосов
/ 05 марта 2015

как мы знаем, это очень «ошибочная» ситуация. и это меня очень беспокоит.

Сегодня я решил создать представление как:

выбрать * из таблицыName где столбец похож на '% key%'

затем загрузите это представление в EF.

жизнь становится легкой!

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