Shi*_*hin 1 c# linq ienumerable contains expressionbuilder
我正在尝试构建一个 LINQ 表达式,以从 int 属性中过滤值:
protected IQueryable<T> Some(IEnumerable<int> ids)
{
var parameter = Expression.Parameter(typeof(T), "x");
// "Col_id" (int property)
var property = Expression.Property(parameter, "Col_id");
MethodInfo method = typeof(Enumerable).
GetMethods().
Where(x => x.Name == "Contains").
Single(x => x.GetParameters().Length == 2).
MakeGenericMethod(typeof(T));
// ids = { 2, 4, 8 } etc...
var value = Expression.Constant(ids, typeof(IEnumerable<int>));
var containsMethod = Expression.Call(method, property, value); // exception
var aDelegate = Expression.Lambda<Func<T, bool>>(containsMethod, parameter);
table = myDataContext.GetTable<T>();
return table.AsQueryable().Where(aDelegate);
}
Run Code Online (Sandbox Code Playgroud)
我试图得到类似的东西:(x => ids.Contains(x.Col_id)),但抛出异常:
'System.Int32' 类型的表达式不能用于类型参数 'System.Collections.Generic.IEnumerable'1[T] from 'Boolean Contains[T](System.Collections.Generic.IEnumerable'1[T], T) ' 方法
在我看来,你的论点是错误的。
这个:
Expression.Call(method, property, value)
Run Code Online (Sandbox Code Playgroud)
意味着你在打电话:
Enumerable.Contains(x.Col_id, ids)
Run Code Online (Sandbox Code Playgroud)
而你想要
Enumerable.Contains(ids, x.Col_id)
Run Code Online (Sandbox Code Playgroud)
所以试试吧:
var containsMethod = Expression.Call(method, value, property);
Run Code Online (Sandbox Code Playgroud)
编辑:接下来Contains,我认为您正在构建错误的类型参数。我怀疑你想要:
MethodInfo method = typeof(Enumerable).
GetMethods().
Where(x => x.Name == "Contains").
Single(x => x.GetParameters().Length == 2).
MakeGenericMethod(typeof(int));
Run Code Online (Sandbox Code Playgroud)
毕竟,您想要调用Enumerable.Contains<int>,而不是Enumerable.Contains<SomeType>。