String.Equals () не работает должным образом - PullRequest
34 голосов
/ 22 февраля 2011

Я использую LINQ для поиска в одной из моих таблиц Entity Framework и нахождения «группы» по названию. Имя является строкой и выглядит как Unicode (говорит, что оно в edmx). У меня есть метод GetGroup(), и я передаю имя для поиска. Отладка с помощью кода, у меня уже есть группа с именем «Test» в моей базе данных. Как только я перейду в группу с именем «TEST», я ожидаю, что она вернет «Test», который уже был в базе данных. По какой-то причине он не находит «Тест» и думает, что «ТЕСТ» не существует. Вот мой запрос, я не могу понять, почему он не работает. Пожалуйста, помогите.

«имя» - это имя, переданное в имени группы. Мой .Equals, кажется, работает, только если gr.Name и имя совпадают. Если в одной из двух строк прописными буквами является один символ, то .Equals не работает. Я пытался использовать InvariantCultureIgnoreCase, и это, похоже, не помогло. Если кто-то спросит, MyLeagueId и LeagueId всегда будут совпадать, база данных настроена так, что может быть группа с другим идентификатором лиги. Я не думаю, что это проблема.

Group g = (from gr in this.DatabaseConnection.Groups
           where gr.Name.Equals(name, StringComparison.OrdinalIgnoreCase) &&
           gr.LeagueId == this.MyLeagueId
           select gr).FirstOrDefault();

Ответы [ 6 ]

39 голосов
/ 23 февраля 2011

При использовании LINQ to Entities он автоматически преобразует его в LINQ to SQL.И если поле базы данных, в котором вы выполняете .Equals, не имеет сопоставления NOCASE (SQLite в моем примере), то оно всегда будет чувствительно к регистру.Другими словами, база данных определяет, как выполнять сравнение строк, а не код.

33 голосов
/ 10 апреля 2014

Сравнение строк с StringComparison.OrdinalIgnoreCase работает в памяти или с IEnumerable<T>. Вы пытаетесь использовать его с IQueryable<T>, но поставщик вашего запроса не понимает этого.

Это работает для меня:

db.Users.FirstOrDefault(
     s => s.Username.Equals(username, StringComparison.OrdinalIgnoreCase)
);
9 голосов
/ 22 февраля 2011

Сделал некоторые исследования.Вы не можете сделать.Параметры сортировки (тип сравнения) определяются на уровне столбца таблицы.Вы не можете изменить его через EF.Если он определен как нечувствительный к регистру, то все поиски будут нечувствительными к регистру.Если он определен как чувствительный к регистру, то ваша единственная надежда - ToUpper() строки.

http://connect.microsoft.com/VisualStudio/feedback/details/435783/entity-framework-conceptual-model-doesnt-support-string-equals-via-linq

http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/3810aa67-f6fe-4624-a14b-eaaa0e05ddcd

EF4 Linq Oracle11g делает запросыбез учета регистра

LINQ to Entities сравнение с учетом регистра

6 голосов
/ 23 декабря 2014

Используйте String.Compare(), так как он может быть переведен в Sql.

Здесь - некоторые примеры сопоставления строк в Linq, а также перевод Sql.

4 голосов
/ 04 октября 2012

Мне нравится ответ TravyGuy с технической точки зрения.Для более прямого и практического ответа попробуйте использовать:

string.Compare(string A, string B, StringComparison.OrdinalIgnoreCase) == 0
3 голосов
/ 22 февраля 2011

Попробуйте name.Equals(gr.Name, StringComparison.OrdinalIgnoreCase)

Если это работает, то проблема может быть в gr.Name.

--- Редактировать ---

Я предполагаю, что gr.Name не относится к типу System.string. (поскольку String.Equals выдает ошибку ==> из предыдущего поста)

дай этому шанс

(gr.Name as string).Equals(name, StringComparison.OrdinalIgnoreCase)

или

String.Equals((gr.Name as string), name, StringComparison.OrdinalIgnoreCase)
...