表达式树中的简单Where子句

发布于 2024-12-04 07:57:41 字数 898 浏览 0 评论 0 原文

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

谢谢。

I am attempting to build a simple Where clause.

This is the code that does not work:

EDIT this code works fine now (thanks to answers below).

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

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落在眉间の轻吻 2024-12-11 07:57:41

您的代码存在几个问题:

  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>(_Body, _Param);
    
  4. 列表实现 IEnumerable,但不实现 IQueryable

    IEnumerable;与委托一起工作,而 IQueryable适用于表达式树。

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

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

    或将列表转换为 IQueryable

    var _Where = Expression.Lambda>(_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);

There are several problems with your code:

  1. You need to pass 1 and not "1" for the integer constant 1.

    var _Right = Expression.Constant(1, _Prop.PropertyType);
    
  2. Expression.Equals if two expression trees are equal. It returns a bool.

    Expression.Equal returns an expression tree that represents an equality check.

    var _Body = Expression.Equal(_Left, _Right);
    
  3. The parameter is of type Item and not int.

    var _Where = Expression.Lambda<Func<Item, bool>>(_Body, _Param);
    
  4. The List<T> implements IEnumerable<T>, but not IQueryable<T>.

    IEnumerable<T> works with delegates, while IQueryable<T> works with expression trees.

    So you need to either compile your expression tree to a delegate

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

    or convert the list to IQueryable<T>.

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

Working code:

// 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文