c# - 表达式树中的简单 Where 子句

标签 c# expression-trees where-clause

我正在尝试构建一个简单的 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 而不是 "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. 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/

相关文章:

c# - 等待 MongoConnection 超时

c# - 生成带有一些透明部分的图像

c# - 使用 foreach 循环构建自定义谓词以充当过滤器

c# - 如何在 C# 中创建表达式树来表示 'String.Contains("term")'?

python - 数据库列中的换行符和空格

sql - 将 WHERE 与 SUM 函数 SQL 结合使用

sql - PL SQL - 多列相等

c# - 调用正在运行的进程的方法

c# - 如何根据约定创建返回受限属性集的表达式树?

c# - Xamarin.UI 测试 NU1201 错误 : Android 8. 1 与 .NET Framework 4.6.1 不兼容