数组到二进制表达式

时间:2017-01-15 07:51:06

标签: c# linq

给定x => x.LastName

如何转换.Where({"Doe", "Don", "Donna"}.Contains(x.LastName))之类的内容?

我需要将此.Contains表达式转换为

.Where(x => x.LastName == "Doe" || x.LastName == "Don" || x.LastName == "Donna")

所以基本上给出了数组{"Doe", "Don", "Donna"}和成员表达式x.LastName,如何动态构建如上所述的有效BinaryExpression

好的一点背景,我正在尝试为NoSQL数据库构建一个LINQ接口,该数据库不知道如何处理Enumerable.Contains MemberCallExpression。因此,我尝试将Enumerable.Contains转换为数据库可以处理的简单OrElse表达式。

我可以从x.LastName' MemberCallExpression获得Arguments[0],我已经想出如何从表达式中获取可枚举的常量,我已经能够通过枚举常量并说

来构建List<BinaryExpression>
Expressions.Add(Expression.Equal(node.Arguements[0], Expression.Constant(item)));

如何获取BinaryExpression的列表并构建BinaryExpression形式的有效Expressions[0] OrElse Expressions[1] OrElse Expressions[2]

我试过了:

BinaryExpression expression = Expressions[0];
for (var idx = 1; idx < Expressions.Count - 1; idx++)
{
     expression += Expression.OrElse(Expressions[idx], Expressions[idx   +1]);
}

但是+=BinaryExpression上无效。而且我不确定如何将另一个二进制表达式实际附加到现有的BinaryExpression ...

2 个答案:

答案 0 :(得分:0)

string[] arr = {"Doe", "Don", "Donna"};
BinaryExpression exp = null;
MemberExpression member = ... //get the "x.LastName" expression
foreach (String name in arr) {
    BinaryExpression eq = Expression.Equal(member, name);
    if (exp == null) {
        exp = eq;
    }
    else {
        exp = Expression.OrElse(exp, eq);
    }
}

Type delegateType = typeof(Func<T, bool>); //T is your entity type, e.g. Person
ParameterExpression arg = ... //the "x" in "x.LastName"

//construct the lambda expression x => [expr].
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);

然后,您可以将其提供给.Where()

.Where(lambda);

答案 1 :(得分:0)

我将留下我之前的答案供将来参考,因为我认为表达式构建并不容易,因此该示例可能对某些人有用。至于问题,链接表达式非常简单。你应该使用Expression.OrElse方法:

BinaryExpression expression = Expressions[0];
for (var idx = 1; idx < Expressions.Count - 1; idx++)
{
    expression = Expression.OrElse(expression, Expressions[idx]);
}