我正在尝试构建一个简单的 Where 子句。
这是行不通的代码:
编辑这段代码现在可以正常工作(感谢下面的答案)。
public class Item
{
public int Value { get; set; }
public string Name { get; set; }
}
var _List = new List<Item>
{
new Item{ Name = "Smith", Value = 1},
new Item{ Name = "Smith", Value = 2},
new Item{ Name = "Wesson", Value = 3},
new Item{ Name = "Wesson", Value = 4},
};
// Where(x => x.Value == 1)
var _Type = typeof(Item);
var _Prop = _Type.GetProperty("Value");
var _Param = Expression.Parameter(_Type, _Prop.Name);
var _Left = Expression.PropertyOrField(_Param, _Prop.Name);
var _Right = Expression.Constant(1, _Prop.PropertyType);
var _Body = Expression.Equal(_Left, _Right);
var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param);
var _Result = _List.AsQueryable().Where(_Where);
谢谢。
最佳答案
你的代码有几个问题:
您需要为整数常量
1
传递1
而不是"1"
。var _Right = Expression.Constant(1, _Prop.PropertyType);
Expression.Equals 如果两个表达式树相等。它返回一个
bool
。Expression.Equal 返回表示相等性检查的表达式树。
var _Body = Expression.Equal(_Left, _Right);
参数的类型是
Item
,不是int
。var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param);
List
实现 IEnumerable ,但不实现 IQueryable 。 IEnumerable
使用委托(delegate),而 IQueryable 使用表达式树。 因此您需要将表达式树编译为委托(delegate)
var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param).Compile(); var _Result = _List.Where(_Where);
或将列表转换为 IQueryable
。 var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param); var _Result = _List.AsQueryable().Where(_Where);
工作代码:
// Where(x => x.Value == 1)
var _Param = Expression.Parameter(typeof(Item), "x");
var _Left = Expression.PropertyOrField(_Param, "Value");
var _Right = Expression.Constant(1);
var _Body = Expression.Equal(_Left, _Right);
var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param).Compile();
var _Result = _List.Where(_Where);
关于c# - 表达式树中的简单 Where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7391450/