How to make LINQ execute a (SQL) LIKE range search

The problem here is that expressions containing Regex can’t be translated to SQL, so even when you’d succeed in building a correct expression, you can’t use it in LINQ to a SQL backend. However, SQL’s LIKE method also supports range wildcards like [0-9], so the trick is to make your LINQ translate to SQL containing a LIKE statement.

LINQ-to-SQL offers the possibility to use the SQL LIKE statement explicitly:

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

This SqlMethods class can only be used in LINQ-to-SQL though. In Entity Framework there are string functions that translate to LIKE implicitly, but none of them enable the range wildcard ([x-y]). In EF a statement like …

return namesList.OrderBy(r => r.Name.StartsWith("[0-9]")) ...

… would translate to nonsense:

[Name] LIKE '~[0-9]%' ESCAPE '~'

I.e. it vainly looks for names starting with the literal string “[0-9]”. So as long as you keep using LINQ-to-SQL SqlMethods.Like is the way to go.

In Entity Framework 6.1.3 (and lower) we have to use a slightly different way to obtain the same result …

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

… because PatIndex in SqlFunctions also supports range pattern matching.

But in Entity Framwork 6.2 we’re back on track with LINQ-to-SQL because of the new DbFunctions.Like function:

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

Finally, also Entity Framework core has a Like function:

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

Leave a Comment

tech