给定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 ...
答案 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]);
}