将参数从lambda函数更改为lambda表达式

时间:2009-03-24 15:02:37

标签: c# lambda

我有扩展方法:

public static IQueryable<TResult> WithFieldLike<TResult>(
   this IQueryable<TResult> query,
   Func<TResult, string> field,
   string value)
{
   Expression<Func<TResult, bool>> expr = 
       trans => field(trans).Contains(value);
   return query.Where(expr);
}

我需要更改参数字段以输入:Expression&gt;。会是这样的。

public static IQueryable<TResult> WithFieldLike<TResult>(
   this IQueryable<TResult> query,
   Expression<Func<TResult, string>> field,
   string value)
{
   Expression<Func<TResult, bool>> expr = ???
   return query.Where(expr);
}

此方法的调用是:

var query7 = query.WithFieldLike(trans => trans.DeviceModelNumber, "ber_3");

在这种情况下我应该如何构建“expr”?请帮忙。

3 个答案:

答案 0 :(得分:6)

解构field并创建一个新的表达式,如下所示:

var expr = Expression.Lambda<Func<TResult, bool>> (
    Expression.Call (field.Body, typeof (string).GetMethod ("Contains"),
        Expression.Constant (value)), field.Parameters) ;

(根据Maxs在评论中的改进编辑)

答案 1 :(得分:4)

您需要使用Expression.Invoke;像(未经测试的):

public static IQueryable<TResult> WithFieldLike<TResult>(
   this IQueryable<TResult> query,
   Expression<Func<TResult, string>> field,
   string value)
{
    var param = Expression.Parameter(typeof(TResult), "x");
    var expr = Expression.Lambda<Func<TResult, bool>>(
        Expression.Call(Expression.Invoke(field, param),
            "Contains", null, Expression.Constant(value)), param);

    return query.Where(expr);
}

(编辑:修复)

答案 2 :(得分:1)

使用Compile让lambda退出:

Expression<Func<TResult, bool>> expr = 
   trans => field.Compile()(trans).Contains(value);

编辑:哎呀 - 我的空中编译器让我失望了。编译后,您将获得委托。但是,你仍然需要调用它来获取字符串来调用Contains。