EF Core 3.0 переводит строку. Equals ordinalIgnoreCase правильно

До EF Core 3.0 это работало нормально (оценивалось на сервере + клиенте):

var exists = await _context.Countries.AsNoTracking().AnyAsync(x => x.CountryCode.Equals(country.CountryCode, StringComparison.OrdinalIgnoreCase));

Какой метод является лучшим / предпочтительным для перевода части string.Equals(str, StringComparison.OrdinalIgnoreCase) сейчас в EF Core 3.0, чтобы запрос выполнялся только на стороне сервера.

var exists = await _context.Countries.AsNoTracking().AnyAsync(x => x.CountryCode.ToUpper() == country.CountryCode.ToUpper());

or

var exists = await _context.Countries.AsNoTracking().AnyAsync(x => x.CountryCode.ToLower() == country.CountryCode.ToLower());

or

var exists = await _context.Countries.AsNoTracking().AnyAsync(x => x.CountryCode.ToUpperInvariant() == country.CountryCode.ToUpperInvariant());

or

var exists = await _context.Countries.AsNoTracking().AnyAsync(x => x.CountryCode.ToLowerInvariant() == country.CountryCode.ToLowerInvariant());

или что-то другое?


person juFo    schedule 31.10.2019    source источник
comment
Это ошибка кода, а не проблема с EF. Чувствительность к регистру контролируется параметрами сортировки столбца. Если в столбце используется сопоставление с учетом регистра в, вы получите сопоставление без учета регистра. Индексы также используют сопоставление, поэтому попытка сопоставления с использованием разных правил или, что еще хуже, применение любых функций не позволяет серверу использовать какие-либо индексы.   -  person Panagiotis Kanavos    schedule 31.10.2019
comment
Настоящее решение было опубликовано Л.Трабачиным. Удалить Equals* altogether and ensure the column uses a case-insensitive collation. All the snippets posted in the question will result in a bad query. x = ›x.CountryCode. == country.CountryCode` будет работать нормально   -  person Panagiotis Kanavos    schedule 31.10.2019
comment
Кстати, это означает, что в вашем коде уже была серьезная ошибка производительности, которая была обнаружена из-за того, что EF Core отключил оценку на стороне клиента. До сих пор ваш запрос загружал все в память клиента перед фильтрацией.   -  person Panagiotis Kanavos    schedule 31.10.2019


Ответы (1)


Вы не должны делать этого или использовать принятый метод ответа, вы должны просто использовать String.Equals () без параметров и настроить параметры сортировки базы данных во время создания или миграции.

person L.Trabacchin    schedule 31.10.2019
comment
Похоже, сегодня я узнал что-то новое. Спасибо. Правильно ли я, что по умолчанию регистр уже не учитывается (Latin1_General_CI_AS)? - person juFo; 31.10.2019
comment
Обычно это так, но если вам это необходимо, просто убедитесь, что это так. Взгляните: есть несколько способов сделать это: stackoverflow.com/questions/12054930/ - person L.Trabacchin; 31.10.2019
comment
Как мы поддерживаем эти сценарии: в одном запросе мне нужно быть чувствительным к регистру, а в другом - без учета регистра. например. наш поиск должен быть нечувствительным к регистру, но тогда я хочу загружать по точному совпадению, когда я работаю с сущностью. - person Petr J; 03.02.2021
comment
ef core support custom query ... настройте сценарий по умолчанию, затем используйте настраиваемый docs.microsoft.com/en-us/ef/core/querying/raw-sql - person L.Trabacchin; 03.02.2021