在动态链接查询中调用Regex.IsMatch()

krcsximq  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(127)

我尝试调用Regex.IsMatch()并在动态linq查询中计算返回的结果。

public static LambdaExpression Parse(SearchQuery query)
{
    string compilableExpression = "Regex.IsMatch(Category.ToLower(), \"\\bSomeCat\\b\", RegexOptions.Compiled) == true";

    ParameterExpression parameter1 = System.Linq.Expressions.Expression.Parameter(typeof(EventListItem));
    ParameterExpression parameter2 = System.Linq.Expressions.Expression.Parameter(typeof(Regex));

    return System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { parameter1, parameter2 }, null, compilableExpression);
}

在本例中,CategoryEventListItem中的属性。调用ParseLambda()时引发此异常:
Unknown identifier 'Regex' .
是否有方法调用该方法?我遇到了Expression.Call()方法,但我不确定这是否是我要找的。任何帮助都是感激不尽的。

lc8prwob

lc8prwob1#

我没有经常使用System.Linq.Dynamic,但这里有一种方法可以让您的示例正常工作:
1 -您实际上只有一个输入对象,即EventListItem,因此删除parameter 2(Regex):

string compilableExpression = "Regex.IsMatch(Category.ToLower(), \"\\bSomeCat\\b\", RegexOptions.Compiled) == true";
ParameterExpression parameter1 = System.Linq.Expressions.Expression.Parameter(typeof(EventListItem));
return System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { parameter1 }, null, compilableExpression);

2 -DynamicExpression.ParseLambda()用于从 input object 读取属性和方法。使用其他类上的方法(此处为:Regex.IsMatch()仅限于一小组预定义的类,默认情况下,Regex不在其中。
因此,我们需要设法让解析器认识到“Regex”是一个类,而不是EventListItem上的属性。假设您已经在项目中包含了DynamicLinq.cs文件,这可以通过将Regex(和RegexOptions)添加到内部ExpressionParser.predefinedTypes数组来完成:

static readonly Type[] predefinedTypes = {
    typeof(Object),
    typeof(Boolean),
    ...

    typeof(System.Text.RegularExpressions.Regex), 
    typeof(System.Text.RegularExpressions.RegexOptions),
};

编辑:复杂参数值

如果我们需要在方法调用中包含更复杂的参数,例如组合的RegexOptions枚举; RegexOptions.Compiled | RegexOptions.IgnoreCase,ParseLambda也接受values的列表。
我们事先准备好了组合枚举,并在值列表中提交它。在compilableExpression中,我们为提交的值添加了占位符,并按照提交顺序进行索引(这里我们只有一个值-索引0)

var options = RegexOptions.Compiled | RegexOptions.IgnoreCase;
string compilableExpression = "Regex.IsMatch(Category.ToLower(), \"\\bSomeCat\\b\", @0) == true";
ParameterExpression parameter1 = SLE.Expression.Parameter(typeof(EventListItem));
return SLD.DynamicExpression.ParseLambda(new[] { parameter1 },
                                         null,
                                         compilableExpression,
                                         options);
  • 额外好处:因为RegexOptions类/枚举不再直接在compilableExpression中引用,所以我们也不再需要在ExpressionParser. predefinedTypes中包含RegexOptions。*

相关问题