[英]Natural sorting with LINQ to Entities
I've tried to implement natural sorting with LINQ to Entities, using the equivalent of this SQL statement: 我试图使用LINQ to Entities来实现自然排序,使用此SQL语句的等效项:
ORDER BY case when name like '[0-9]%' then 1 else 0 end, name
My LINQ query is: 我的LINQ查询是:
query.OrderByDescending(a => a.Name.StartsWith("[0-9]") ? 1 : 0)
LINQ to Entities though is adding a tilde (~) in the pattern. LINQ to Entities在模式中添加了波浪号(〜)。
It's generating an SQL query like this: 它正在生成这样的SQL查询:
SELECT CASE WHEN (Extent1.name LIKE '~[0-9]%' escape '~') THEN 1 ELSE 0 END AS [C1], name
from accounts extent1
order by c1 asc
How can I remove tilde (~) that has been appended after, like '~[0-9]%' ? 如何删除后面附加了波浪号(〜),例如'〜[0-9]%' ?
There's nothing wrong with the generated query, it's exactly as it should be. 生成的查询没有任何问题,完全正确。 Your query asks for names that start with the exact string
[0-9]
. 您的查询要求输入以精确字符串
[0-9]
开头的名称。
String.StartsWith(x)
is a string method that checks whether a string starts with a literal, without pattern matching. String.StartsWith(x)
是一个字符串方法,该方法检查字符串是否以文字开头而不进行模式匹配。 Linq to Entities translates this LIKE 'x%'
where x
is a literal string, not a pattern. Linq to Entities会转换此
LIKE 'x%'
,其中x
是文字字符串,而不是模式。 [
is a special character in a LIKE statement though. [
尽管是LIKE语句中的特殊字符。 This means that it has to be escaped with LIKE '~[0-9]%' escape '~'
. 这意味着必须使用
LIKE '~[0-9]%' escape '~'
对其进行转义。 The LIKE
operator allows you to specify the escape character, in this case ~
. LIKE
运算符允许您指定转义字符,在这种情况下为~
。
I suspect that you didn't want names starting with [0-9]
though, but those that start with a digit, ie LIKE '[0-9]%'
. 我怀疑您虽然不希望名称以
[0-9]
开头,但是希望以数字开头,例如LIKE '[0-9]%'
。 String.StartsWith doesn't support patterns nor is there another String
method that does. String.StartsWith不支持模式,也没有其他
String
方法支持。
One solution is to use SqlFunctions.PatIndex in your query and filter for rows that return 1. I'd check the execution plan though, because I suspect the query will be slower. 一种解决方案是在查询中使用SqlFunctions.PatIndex并过滤返回1的行。但是我会检查执行计划,因为我怀疑查询会变慢。
LIKE '[0-9]%
is essentially a range search for all strings that start from 0
up to the letter after 9
excluding, ie A
. LIKE '[0-9]%
本质上是对从0
到9
之后(不包括A
的所有字母的所有字符串进行范围搜索。 This means that the server can use indexes on Name
. 这意味着服务器可以在
Name
上使用索引。 With PATINDEX it may have to process all rows. 使用PATINDEX可能必须处理所有行。
Unfortunately, SqlFunctions
doesn't contain Like
or any similar method that would generate a LIKE
statement with pattern matching. 不幸的是,
SqlFunctions
不包含Like
或任何其他会生成具有模式匹配的LIKE
语句的方法。
Another option is to actually ask for a range query with a.Name >="0" && a.Name <"A"
. 另一个选择是实际要求
a.Name >="0" && a.Name <"A"
的范围查询。
UPDATE - NATURAL SORTING 更新-自然排序
This is a case of the XY Problem . 这是XY问题的情况 。 The actual problem X is how to perform natural sorting with LINQ to Entities.
实际的问题X是如何使用LINQ对实体进行自然排序。 One of the T-SQL solutions for natural sorting is to use a formula in the ORDER BY clause in combination with the name itself , to make numbers appear after plain text, eg:
用于自然排序的T-SQL解决方案之一是将ORDER BY子句中的公式与名称本身结合使用 ,以使数字出现在纯文本之后,例如:
ORDER BY case when name like '[0-9]%' then 1 else 0 end, name
Unfortunately, this doesn't work with EF because there is no equivalent to LIKE
with patterns. 不幸的是,这不适用于EF,因为没有等效于
LIKE
的模式。
The same ordering can be performed with PATINDEX, which is available through the SqlFunctions.PatIndex function : 相同的排序可以用PATINDEX,这是可通过SqlFunctions.PatIndex函数来执行:
order by name, case when PATINDEX('[0-9]%',name)=1 then 1 else 0 end
The equivalent LINQ code could be: 等效的LINQ代码可以是:
query.OrderBy(a => {
SqlFunctions.PatIndex("[0-9]%",a.Name)==1? 1:0,
a.Name
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.