我正在尝试调用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);
}
在这种情况下,Category
是EventListItem
中的属性。调用ParseLambda()
:
Unknown identifier 'Regex'
。
有没有办法调用方法?我遇到了Expression.Call()
方法,但我不确定这是否是我正在寻找的。任何帮助表示赞赏。
答案 0 :(得分:7)
我没有经常使用System.Linq.Dynamic
,但这是让你的例子有效的方法:
1 - 您实际上只有一个输入对象EventListItem
,所以删除参数2(正则表达式):
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()
用于从输入对象中读取属性和方法。在其他类上使用方法(此处:Regex.IsMatch()
仅限于一小组预定义类,默认情况下Regex
不是其中之一。
因此,我们需要让解析器意识到“Regex”是一个类,而不是EventListItem上的属性。假设您已在项目中包含DynamicLinq.cs file,可以通过将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);
Bonus:因为compilableExpression中不再直接引用RegexOptions类/枚举,所以我们也不再需要在ExpressionParser.predefinedTypes中包含RegexOptions。