生成的查询没有任何问题,完全按照它的样子。您的查询要求输入以确切字符串[0-9]
开头的名称。
String.StartsWith(x)
是一个字符串方法检查字符串是否以文字开头,没有模式匹配。 Linq to Entities翻译此LIKE 'x%'
其中x
是一个文字字符串,而不是一个模式。 [
虽然是LIKE语句中的特殊字符。这意味着它必须用LIKE '~[0-9]%' escape '~'
进行转义。 LIKE
运算符允许您指定转义字符,在这种情况下为~
。
我怀疑你不希望名字以[0-9]
开头,但是那些以数字开头的名字,即LIKE '[0-9]%'
。 String.StartsWith不支持模式,也没有另一个String
方法。
一个解决方案是在您的查询中使用SqlFunctions.PatIndex,并为返回的行过滤。我会检查执行计划,因为我怀疑查询会变慢。 LIKE '[0-9]%
本质上是范围搜索的所有字符串,从0
开始到9
之后的字母排除,即A
。这意味着服务器可以使用Name
上的索引。使用PATINDEX可能需要处理所有行。
不幸的是,SqlFunctions
不包含Like
或任何类似的方法,将生成LIKE
语句模式匹配。
另一种选择是实际询问a.Name >="0" && a.Name <"A"
的范围查询。
更新 - 自然排序
这是XY Problem的情况。实际问题X是如何使用LINQ to Entities执行自然排序。一个自然排序的T-SQL的解决方案是按照下面的顺序组合使用公式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 server中得到结果。它没有逃脱。 – Aby
您的查询请求以[[0-9] ** ** EXACTLY **开头的名称。你要求'[0-9] George'和'[0-9] Pete',而不是'0George'。通过删除转义字符,您可以执行完全不同的查询。你不能使用'StartsWith'的模式匹配。你是否试图找到以数字开头的名字? –