Изменить параметр с лямбда-функции на лямбда-выражение - PullRequest
7 голосов
/ 24 марта 2009

У меня есть метод расширения:

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

Мне нужно изменить поле параметра, чтобы ввести: Выражение>. Будет что-то вроде.

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 ]

6 голосов
/ 24 марта 2009

Разобрать field и создать новое выражение, что-то вроде этого:

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

(отредактировано в соответствии с уточнением Максса в комментариях)

4 голосов
/ 24 марта 2009

Вам нужно будет использовать 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);
}

(редактировать: исправлено)

1 голос
/ 24 марта 2009

Используйте Компиляция , чтобы вернуть лямбду:

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

Редактировать: Упс, мой авиакомпилятор подвел меня. После компиляции вы получаете делегата. Но вам все равно нужно вызвать его, чтобы получить строку для вызова Contains.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...