1

我正在尝试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()方法,但我不确定这是否是我正在寻找的。任何帮助表示赞赏。

4

1 回答 1

8

我没有使用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 文件,这可以通过将 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。

于 2013-05-22T00:56:27.257 回答