Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change parameter from lambda function to lambda expression

Tags:

c#

lambda

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.

like image 687
Maxs Avatar asked Mar 24 '09 15:03

Maxs


2 Answers

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)

like image 200
Anton Tykhyy Avatar answered Nov 11 '22 00:11

Anton Tykhyy


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)

like image 40
Marc Gravell Avatar answered Nov 10 '22 23:11

Marc Gravell