简单表达式树中的子句

时间:2011-09-12 17:13:18

标签: c# expression-trees where

我正在尝试构建一个简单的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 个答案:

答案 0 :(得分:4)

您的代码存在一些问题:

  1. 您需要为1而不是"1"传递整数常量1

    var _Right = Expression.Constant(1, _Prop.PropertyType);
    
  2. Expression.Equals如果两个表达式树相等。它返回bool

    Expression.Equal返回表示相等性检查的表达式树。

    var _Body = Expression.Equal(_Left, _Right);
    
  3. 参数属于Item,而非int

    var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param);
    
  4. 列表&lt; T&gt;实现IEnumerable&lt; T&gt;,但不是IQueryable&lt; T&gt;。

    的IEnumerable&LT; T&GT;与代表合作,而IQueryable&lt; T&gt;适用于表达树。

    因此,您需要将表达式树编译为委托

    var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param).Compile();
    var _Result = _List.Where(_Where);
    

    或将列表转换为IQueryable&lt; T&gt;。

    var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param);
    var _Result = _List.AsQueryable().Where(_Where);
    
  5. 工作代码:

    // 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);