使用lambda表达式动态设置比较运算符 [英] Set comparison operator dynamically using lambda expression

查看:150
本文介绍了使用lambda表达式动态设置比较运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要在linq查询中动态设置一个比较运算符,请执行以下操作:

To set a comparison operator in linq query dynamically, i do the following:

parameter = Expression.Parameter(typeof(SomeType));
var predicate = Expression.Lambda<Func<SomeType, bool>>(
    Combine(
        "=",
        Expression.Property(parameter, "ID"),
        Expression.Constant(150497)
    ), parameter);

BinaryExpression Combine(string op, Expression left, Expression right)
{
    switch (op)
    {
        case "=":
            return Expression.Equal(left, right);
        case "<":
            return Expression.LessThan(left, right);
        case ">":
            return Expression.GreaterThan(left, right);
    }
    return null;
}

但是我宁愿将lambda表达式作为参数left替代。那可能吗?例如:

That works. But I'd rather pass a lambda expression as parameter "left" instead. Is that possible? Something like:

var predicate = Expression.Lambda<Func<SomeType, bool>>(Combine(
    "=",
    c => c.ID,
    Expression.Constant(150497)
), parameter);


推荐答案

不幸的是,我现在不能测试,所以如果不行,请给我知道。

What about this? Unfortunately, I cannot test it now, so give me know if it doesn't work

private class TestCalss
{
    public int Id { get; set; }
}

private class SwapVisitor : ExpressionVisitor
{
    public readonly Expression _from;
    public readonly Expression _to;

    public SwapVisitor(Expression from, Expression to)
    {
        _from = from;
        _to = to;
    }

    public override Expression Visit(Expression node) => node == _from ? _to : base.Visit(node);
}

private BinaryExpression Combine<T, TResult>(string op, Expression<Func<T, TResult>> left, Expression right, ParameterExpression parameter)
{
    // Need to use parameter from outer lambda expression for equality two expressions 
    var swap = new SwapVisitor(left.Parameters[0], parameter);
    var newLeft = swap.Visit(left) as Expression<Func<T, TResult>>;
    switch (op)
    {
        case "=":
            return Expression.Equal(newLeft.Body, right);
        case "<":
            return Expression.LessThan(newLeft.Body, right);
        case ">":
            return Expression.GreaterThan(newLeft.Body, right);
    }
    return null;
}

...
var parameter = Expression.Parameter(typeof(TestCalss));
var predicate = Expression.Lambda<Func<TestCalss, bool>>(
    Combine<TestCalss, int>("=", c => c.Id, Expression.Constant(156), parameter),
    parameter);
var test = new TestCalss { Id = 156 };
var result = predicate.Compile()(test); // <- true

这篇关于使用lambda表达式动态设置比较运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆