2

how to invoke Regex.IsMatch() in IQueryable? i found the same question but it doesnt work Invoking Regex.IsMatch() inside a dynamic linq query

first i have

IQueryable Database = data.Verses.Select($"new {{ ID, {TextSearchType.ToString()} }}");

ive tried

var searchResult = Database.Where(Parse());

public static LambdaExpression Parse()
{
    ParsingConfig.Default.CustomTypeProvider = new MyCustomTypeProvider();
    var options = RegexOptions.IgnoreCase;
    string compilableExpression = $"Regex.IsMatch({TextSearchType.ToString()}, \"(^| ){Keyword}($| )\", @0) == true";
    ParameterExpression parameter = Expression.Parameter(typeof(Verses));
    var DynamicExpression = DynamicExpressionParser.ParseLambda(new[] { parameter },
                                             null,
                                             compilableExpression,
                                             options);
    return DynamicExpression;
}
public class MyCustomTypeProvider : DefaultDynamicLinqCustomTypeProvider
{
    public override HashSet<Type> GetCustomTypes()
    {
        return new HashSet<Type>
                {
                    typeof(Object),
                    typeof(Boolean),
                    typeof(System.Text.RegularExpressions.Regex),
                    typeof(System.Text.RegularExpressions.RegexOptions),
                };
    }
}

TextSearchType is property name in Verses class. im getting this error

No generic method 'Where' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

here is the linq code the im trying to convert to linq dynamic

var rx = new Regex("(^| )" + keyword + "($| )", RegexOptions.IgnoreCase);
var searchResult = Database.AsEnumerable()
            .Where(x => rx.IsMatch(x.AyahText)).ToList();
Airn5475
  • 2,452
  • 29
  • 51
msd
  • 37
  • 1
  • 7

1 Answers1

2

You can not call IsMatch or any other Non-SQL supported functions (see the full list here) in LINQ to Entities.

In order to do what you want, you to have two possible options (maybe more, but I know two at this moment):

  1. Get the items by raw filtering (without using IsMatch), converting the result to List, by calling .ToList() at the end of your query. And then you can filter the collection by Regex.IsMatch.
    To be honest, this is not a greater solution, and I wouldn't say I like it.
  2. Create a stored procedure and call it from the c# (official documentation here).
Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42