如何使 LINQ 执行 (SQL) LIKE 范围搜索

R. *_*oca 5 c# sql linq asp.net linq-to-sql

我非常需要帮助,我已经尝试这样做有一段时间了。

所以我有这个查询:

Select name from BlaBlaBla

order by 

case when name like '9%' then 1 end,
case when name like '8%' then 1 end,
case when name like '7%' then 1 end,
case when name like '6%' then 1 end,
case when name like '5%' then 1 end,
case when name like '4%' then 1 end,
case when name like '3%' then 1 end,
case when name like '2%' then 1 end,
case when name like '1%' then 1 end,
case when name like '0%' then 1 end,

name
Run Code Online (Sandbox Code Playgroud)

我想在我的解决方案中的新 C#、Asp.Net 类中将其实现到域项目,因此它将是一个 OrderType 过滤器,用于某些功能...

现在我有这个:

var param = Expression.Parameter(typeof(T), "item");

var paramName = Expression.Property(param, "Name");
var regexMatch = Expression.Constant("^[0-9]");
var startsWithDigit = Expression.Call(typeof(Regex), "IsMatch", 
                                             null, paramName);

var lambda = Expression.Lambda<Func<T, bool>>(startsWithDigit, 
                                              param);

return namesList.OrderBy(lambda)
           .ThenBy(BlaBla1())
           .ThenByDescending(BlaBla2())
           .ThenByDescending(BlaBla3())
           .ThenBy(BlaBla4());
Run Code Online (Sandbox Code Playgroud)

但它告诉我,表达式不包含“IsMatch”方法。

你能帮我么?谢谢你!!!

Ger*_*old 4

这里的问题是包含的表达式Regex无法转换为 SQL,因此即使您成功构建了正确的表达式,也无法在 LINQ to SQL 后端中使用它。然而,SQL 的LIKE方法还支持范围通配符,例如[0-9],因此技巧是让 LINQ 转换为包含LIKE语句的 SQL。

LINQ-to-SQL 提供了显式LIKE使用 SQL语句的可能性:

return namesList.OrderBy(r => SqlMethods.Like(r.Name, "[0-9]%")) ...
Run Code Online (Sandbox Code Playgroud)

不过,此SqlMethods类只能在 LINQ-to-SQL 中使用。在实体框架中,有一些字符串函数可以LIKE 隐式转换为,但它们都没有启用范围通配符 ( [x-y])。在 EF 中,像这样的语句...

return namesList.OrderBy(r => r.Name.StartsWith("[0-9]")) ...
Run Code Online (Sandbox Code Playgroud)

...会转化为废话:

[Name] LIKE '~[0-9]%' ESCAPE '~'
Run Code Online (Sandbox Code Playgroud)

即,它徒劳地查找以文字字符串“[0-9]”开头的名称。因此,只要继续使用 LINQ-to-SQLSqlMethods.Like就是正确的选择。

在实体框架 6.1.3(及更低版本)中,我们必须使用稍微不同的方式来获得相同的结果......

return namesList.OrderBy(r => SqlFunctions.PatIndex("[0-9]%", c.Name) == 1) ...
Run Code Online (Sandbox Code Playgroud)

...因为PatIndexSqlFunctions中也支持范围模式匹配。

但在 Entity Framwork 6.2 中,由于新DbFunctions.Like功能,我们又回到了 LINQ-to-SQL 的正轨:

return namesList.OrderBy(r => DbFunctions.Like(r.Name, "[0-9]%")) ...
Run Code Online (Sandbox Code Playgroud)

最后,Entity Framework core还有一个Like功能:

return namesList.OrderBy(r => EF.Functions.Like(r.Name, "[0-9]%")) ...
Run Code Online (Sandbox Code Playgroud)