In my LINQ query I want to check that a numeric string is followed by only non-numeric characters. In regex, it would look something like this: ^[0-9]+[^0-9]*$
However, I've discovered that LINQ can't translate regex.
I've also tried doing the following:
List<char> numbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
var queryableNumbers = numbers.AsQueryable();
from ...
where
...
&& row.content.ToUpper().StartsWith(searchTerm)
&& !queryableNumbers.Any(number => row.content.Substring(searchTerm.Length).Contains(number))
...
Which also doesn't work because LINQ can't translate it for whatever reason. The line !queryableNumbers.Any(number => row.content.Substring(searchTerm.Length).Contains(number))
is the problem.
I've done my best to test all the components in isolation (Contains()
, Any()
, and Substring()
) and it seems that as soon as I put Contains()
inside the Any()
, it fails.
All I can think to do is to keep the first line of the where
block, and move the logic of the second line out of the LINQ query and into an extra loop to filter my results. In other words:
^[0-9]+
^[0-9]+[^0-9]*$
is satisfiedI'd like to avoid an extra loop if possible. At this point I'm stuck. Does anyone have any suggestions for other ways to approach this issue.
Only thing I can think of is to first limit query with LIKE
operator and look only for string that start with number, then in C# code, when query is fetched, filer further the results:
// Get entities which have the field starting with digit.
// [0-9]%" means match one digit and rest is arbitrary.
var semiFiltered = databaseContext.Entities
.Where(x => DbFunctions.Like(x.SemiNumericField, "[0-9]%")
.ToArray();
// Here we use Regex to do the rest
var filtered = semiFiltered
.Where(x => Regex.IsMatch(x.SemiNumericField, "^[0-9]+[^0-9]*$"))
.ToArray();