Есть ли способ добавить System.StringComparison.OrdinalIgnoreCase в startWith в предложении Where в linq C# - PullRequest
0 голосов
/ 10 июля 2020

Я получаю сообщение об ошибке

Невозможно перевести выражение LINQ «DbSet .Where (t => t.ZipCode.StartsWith (value: __zipCode_0, compareType: OrdinalIgnoreCase))». Либо перепишите запрос в форме, которая может быть переведена, либо явно переключитесь на оценку клиента, вставив вызов либо AsEnumerable (), AsAsyncEnumerable (), ToList (), либо ToListAsyn c ().

и это мой код:

await DbSet
     .Where(x => x.ZipCode.StartsWith(zipCode, System.StringComparison.OrdinalIgnoreCase))
     .OrderBy(n => n.ZipCode)
     .ToListAsync(cancellationToken);

Кто-нибудь может мне помочь, пожалуйста? Я попытался удалить StringComparison.OrdinalIgnoreCase, и он работает нормально, но я думаю, это не решение.

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Чувствительность к регистру результатов запросов определяется свойством Collation. Параметры сортировки могут быть определены на разных уровнях.

  • Уровень сервера
  • Уровень базы данных
  • Уровень таблицы
  • Уровень столбца

Параметры сортировки сервера задаются при установке экземпляра. На всех других уровнях, если сопоставление не определено, принимается во внимание значение по умолчанию с более высокого уровня. Чтобы проверить текущее сопоставление сервера, мы можем выполнить следующий запрос:

SELECT Serverproperty ('COLLATION')

Если результат выглядит как “SQL_Latin1_General_CP1_CI_AS”, то он не учитывает регистр.

Причина в параметрах сортировки, «CI» указывает, что параметры сортировки нечувствительны к регистру. Если присутствует "CS", то при сопоставлении будет учитываться регистр.

Если вы обнаружите CI в сопоставлении, запрос выдаст результаты без учета регистра. Нет необходимости снова указывать его в методе StartsWith ().

Я наткнулся на эту замечательную статью, в которой более подробно объясняется сопоставление:

Сопоставление на sql сервере

0 голосов
/ 10 июля 2020

Хотя я согласен с нечувствительностью к регистру Linq to SQL, но реальная проблема, похоже, связана с оценкой запроса Linq ядром EF.

В общем случае вам нужно изучить Client vs. Server Evaluation. Entity Framework Core пытается оценить запрос на сервере в максимально возможной степени. Существует некоторый сценарий ios, в котором проекции клиента верхнего уровня могут быть оценены на стороне клиента, но из-за проблем с производительностью Entity Framework Core блокирует такую ​​оценку клиента и вызывает исключение времени выполнения.

Вы все равно можете запускать как есть без исключения с оценкой на стороне клиента, если ваше требование соответствует следующим двум правилам:

  1. Объем данных невелик, поэтому оценка клиент не сильно снижает производительность.
  2. Используемый оператор LINQ не имеет трансляции на стороне сервера.

В демонстрационных целях я использовал приведенный ниже пример кода, используя AsEnumerable() где значения - это Dbset в моем случае:

var orders =  _context.Values.AsEnumerable()
              .Where(x => x.Name.StartsWith("S", System.StringComparison.OrdinalIgnoreCase))
              .OrderBy(n => n.Name)
              .ToList();

Поскольку ядро ​​EF всегда запускает запросы на стороне сервера, всегда убедитесь, что вы переписываете запросы, чтобы EF мог запускать их на стороне сервера по возможности!

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