Нет ничего плохого в сгенерированном запросе, это точно так, как должно быть. В запросе запрашиваются имена, начинающиеся с точной строки [0-9]
.
String.StartsWith(x)
is string метод, который проверяет, начинается ли строка с литерала, без соответствия шаблону. Linq to Entities переводит этот LIKE 'x%'
, где x
- это буквальная строка, а не шаблон. [
- особый символ в инструкции LIKE. Это означает, что он должен быть экранирован с помощью LIKE '~[0-9]%' escape '~'
. Оператор LIKE
позволяет указать escape-символ, в данном случае ~
.
Я подозреваю, что вам не нужны имена, начинающиеся с [0-9]
, но те, которые начинаются с цифры, то есть LIKE '[0-9]%'
. String.StartsWith не поддерживает шаблоны и не существует другого метода String
.
Одним из решений является использование SqlFunctions.PatIndex в вашем запросе и фильтр для возвращаемых строк 1. Я бы проверял план выполнения, потому что я подозреваю, что запрос будет медленнее. LIKE '[0-9]%
- это поиск по всем строкам, начинающимся с 0
вплоть до буквы после 9
исключая, т. Е. A
. Это означает, что сервер может использовать индексы на Name
. С PATINDEX, возможно, придется обрабатывать все строки.
К сожалению, SqlFunctions
не содержит Like
или любой аналогичный метод, который бы сгенерировал оператор LIKE
с сопоставлением с образцом.
Другой вариант - фактически запросить запрос диапазона с помощью a.Name >="0" && a.Name <"A"
.
ОБНОВЛЕНИЕ - ПРИРОДНЫЙ SORTING
Это случай XY Problem. Фактическая проблема X заключается в том, как выполнять естественную сортировку с помощью LINQ to Entities. Одним из решений T-SQL для естественной сортировки является использование формулы в ORDER BY пункта в сочетании с самого именем, чтобы цифры появляются после того, как простой текст, например:
ORDER BY case when name like '[0-9]%' then 1 else 0 end, name
К сожалению, это Безразлично Не работайте с EF, потому что нет эквивалента LIKE
с узорами.
То же заказ может быть выполнен с PATINDEX, который является доступный через функцию SqlFunctions.PatIndex:
order by name, case when PATINDEX('[0-9]%',name)=1 then 1 else 0 end
Эквивалентный код LINQ может быть:
query.OrderBy(a => {
SqlFunctions.PatIndex("[0-9]%",a.Name)==1? 1:0,
a.Name
})
Вы не потому, что нет ничего плохого. '[' - специальный символ, который нуждается в экранировании, и это то, что делает EF. Запрос правильный, как есть. Вы просили имена, начинающиеся с точной строки '[0-9]'. Если вы не получаете результаты, это потому, что нет строки, которая начинается с точной строки '[0-9]' –
. Я получаю результат в sql-сервере после удаления добавленной тильды (~). Его не сбежали. – Aby
В запросе запрашиваются имена, начинающиеся с '[0-9]' ** ТОЧНО **. Вы запрашиваете '[0-9] George' и' [0-9] Pete', а не '0George'. Удалив escape-символ, вы выполняете совершенно другой запрос. Вы не можете использовать сопоставление с шаблоном 'StartsWith'. Вы пытались найти имена, начинающиеся с числа? –