C# 表达式 - 从另一个表达式创建一个表达式

标签 c# linq-expressions

我正在尝试使用如下所示的表达式创建可重用的方法:

Expression<Func<Order, bool>> CreateExpression(Expression<Func<Order, int>> parameter, FilterOperator operator, int value)

所以我可以这样使用它:

IQueryable<Order> orders = db.Orders;

var filtered = orders.Where(CreateExpression(o => o.OrderID, FilterOperator.GreaterThan, 100));

但我不知道如何编写该方法。我怎样才能编写一个方法来为我创建这个表达式?

我需要能够做这样的事情:

if(operator == FilterOperator.GreaterThan)
   return m => m.OrderID > value;
else if(operator == FilterOperator.LessThan)
   return m => m.OrderID < value;

但是我想使用传入的表达式而不是直接使用OrderID。我怎样才能做到这一点?

最佳答案

static Expression<Func<T, bool>> CreateExpression<T>(Expression<Func<T, int>> parameter, FilterOperator @operator, int value)
{
    var argExpr = Expression.Parameter(typeof(T), "p");
    var paramExpr = Expression.Invoke(parameter, argExpr);
    var constExpr = Expression.Constant(value);
    Expression compExpr = null;
    switch(@operator)
    {
        case FilterOperator.GreaterThan:
            compExpr = Expression.GreaterThan(paramExpr, constExpr);
            break;
        case FilterOperator.LessThan:
            compExpr = Expression.LessThan(paramExpr, constExpr);
            break;
    }

    return Expression.Lambda<Func<T, bool>>(compExpr, argExpr);
}

如果您无法使用 Invoke 并且您的 parameter 表达式是成员表达式,那么您可以使用新参数重新创建它:

static Expression<Func<T, bool>> CreateExpression<T>(Expression<Func<T, int>> parameter, FilterOperator @operator, int value)
{
    var memberExpr = (MemberExpression)parameter.Body;
    PropertyInfo property = (PropertyInfo)memberExpr.Member;

    var argExpr = Expression.Parameter(typeof(T), "p");
    var propertyExpr = Expression.Property(argExpr, property);
    var constExpr = Expression.Constant(value);

    Expression compExpr = null;
    switch(@operator)
    {
        case FilterOperator.GreaterThan:
            compExpr = Expression.GreaterThan(propertyExpr, constExpr);
            break;
        case FilterOperator.LessThan:
            compExpr = Expression.LessThan(propertyExpr, constExpr);
            break;
    }

    return Expression.Lambda<Func<T, bool>>(compExpr, argExpr);
}

关于C# 表达式 - 从另一个表达式创建一个表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13570664/

相关文章:

c# - 表达式的增量值

c# - 如何将 Expression<Func<T, object>> 转换为 Expression<Func<object, object>>

c# - 使用 IsInDateTimeRange 扩展 IQueryable

c# - 使用列名称的字符串列表查询 SQL 表

c# - 客户端使用 OpenPop 进行身份验证时,密码是否需要编码?

c# - Asp.Net MVC 数据注释。如何在 2 个属性相等时获得客户端验证

c# - 了解枚举和 ViewModel

c# - 如何判断一个网址是不是内网网址?

c# - 为什么必须将变量值建模为对表达式树中闭包的成员访问?

c# - 从 Expression<> 中提取 Func<>