вторник, 28 июля 2009 г.

LINQ dynamic expressions. Where

Я как-то писал пример, как можно создать динамическое выражения для сортировки. Сегодня мы рассмотрим еще один пример, как можно написать динамическое выражения для фильтрации по конкретному полю.

Здесь выполняются те же действия, что и в OrderBy, только добавилось еще обращение к значению фильтра 'value'. Пример упрощен тем, что для фильтрации предполагается использование оператора '='.

public static class WhereExtension
{
     /// <summary>Filters input sequence with specified value.</summary>
     /// <param name="query">The query.</param>
     /// <param name="column">The column name to filter.</param>
     /// <param name="value">The value to filter with.</param>
     public static IQueryable<T> Where<T>(this IQueryable<T> query, string column, object value)
     {
          if (string.IsNullOrEmpty(column))
          {
               return query;
          }

          // Where(p => p.{Column} == {value})
          PropertyInfo property = query.ElementType.GetProperty(column);
          ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
          MemberExpression memberAccess = Expression.MakeMemberAccess(parameter, property);
          ConstantExpression filter = Expression.Constant(value);
          BinaryExpression condition = Expression.Equal(memberAccess, filter);
          LambdaExpression lambda = Expression.Lambda(condition, parameter);

          MethodCallExpression result = Expression.Call(
               typeof(Queryable), "Where",
               new [] { query.ElementType},
               query.Expression, 
               lambda);

          return query.Provider.CreateQuery<T>(result);
     }
}

Разобраться не сложно.

Возможности для усовершенствования:
  • Расширить операторы фильтрации, например '>', '<', '<>' и тд.