相关:
Create a Lambda Expression With 3 conditions
Convert Contains To Expression Tree
在上一个问题的下面,我遇到了这个问题,我想写Expression Tree
版本:
List<byte?> lst = new List<byte?>{1,2};
from a in myTbl
where a.Age = 20 && lst.Contains(a.Status)
select a
我写这段代码:
List<byte?> lst = new List<byte?>{1,2};
var param = Expression.Parameter(typeof(T), "o");
var body = Expression.AndAlso(
Expression.Equal(
Expression.PropertyOrField(param, "Age"),
Expression.Constant(20)
),
Expression.Call(Expression.PropertyOrField(param, "Status"),
"Contains",
Type.EmptyTypes,
Expression.Constant(lst)));
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
return lambda;
我收到错误:
“类型'System.Nullable`1 [System.Byte]'上没有方法'包含'。”
请帮我找到问题。
由于
答案 0 :(得分:2)
与Convert Contains To Expression Tree的区别在于我们调用了string
实例 Contains
方法,而在这里我们需要调用 static < / strong>泛型方法Enumerable.Contains
:
public static bool Contains<TSource>(
this IEnumerable<TSource> source,
TSource value
)
可以使用另一个Expression.Call overload
:
public static MethodCallExpression Call(
Type type,
string methodName,
Type[] typeArguments,
params Expression[] arguments
)
像这样:
// Enumerable.Contains<byte?>(lst, a.Status)
var containsCall = Expression.Call(
typeof(Enumerable), // type
"Contains", // method
new Type[] { typeof(byte?) }, // generic type arguments (TSource)
Expression.Constant(lst), // arguments (source)
Expression.PropertyOrField(param, "Status") // arguments (value)
);
答案 1 :(得分:1)
问题是您已将两个参数切换为Expression.Call
,您的代码正在尝试创建无意义的表达式o.Status.Contains(lst)
。
您需要切换两个参数:
Expression.Call(Expression.Constant(lst),
"Contains",
Type.EmptyTypes,
Expression.PropertyOrField(param, "Status"))
这假设您使用的LINQ提供程序理解List<T>.Contains()
。如果您需要Enumerable.Contains()
,请查看Ivan Stoev的回答。