简体   繁体   中英

Change parameter from lambda function to lambda expression

I have extension method:

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

I need change parameter field to type: Expression>. Will be something like.

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

The call of this method is:

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

How should I build the "expr" in this case? Please help.

Deconstruct field and create a new expression, something like this:

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

(edited as per Maxs's refinement in comments)

You'll need to use Expression.Invoke ; something like (untested):

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

(edit: fixed)

Use Compile to get the lambda back out:

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

Edit: Whoops - my air compiler failed me. After compiling, you get the delegate. But, you still need to call it to get the string to call Contains.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM