private IQueryable <TModel> ApplyOperation <TType>(IQueryable <TModel> set, Expression <Func <TModel, TType> > expr, FilterCommand command)
 {
     return(set.Where(GetPredicate(expr, command)));
 }
        private Expression <Func <T, bool> > GetPredicate <T, TType>(Expression <Func <T, TType> > expr, FilterCommand command)
        {
            Expression expression = null;

            try
            {
                switch (command.Operation)
                {
                case FilterOperation.Equal:
                    expression = Expression.Equal(expr.Body, GetConvertedParam <TType>(command.Filter));
                    break;

                case FilterOperation.NotEqual:
                    expression = Expression.NotEqual(expr.Body, GetConvertedParam <TType>(command.Filter));
                    break;

                case FilterOperation.GreaterThan:
                    expression = Expression.GreaterThan(expr.Body, GetConvertedParam <TType>(command.Filter));
                    break;

                case FilterOperation.LesserThan:
                    expression = Expression.LessThan(expr.Body, GetConvertedParam <TType>(command.Filter));
                    break;

                case FilterOperation.StartsWith:
                    expression = Expression.Call(expr.Body, typeof(TType).GetMethod("ToString", new Type[] { }));
                    expression = Expression.Call(expression, typeof(string).GetMethod("ToLower", new Type[] { }));
                    expression = Expression.Call(expression, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), Expression.Constant(command.Filter.ToLower()));
                    break;

                case FilterOperation.Contains:
                    expression = Expression.Call(expr.Body, typeof(TType).GetMethod("ToString", new Type[] { }));
                    expression = Expression.Call(expression, typeof(string).GetMethod("ToLower", new Type[] { }));
                    expression = Expression.Call(expression, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), Expression.Constant(command.Filter.ToLower()));
                    break;
                }
            }
            catch (FormatException)
            {
                expression = Expression.Call(expr.Body, typeof(TType).GetMethod("ToString", new Type[] { }));
                expression = Expression.Call(expression, typeof(string).GetMethod("ToLower", new Type[] { }));
                expression = Expression.Call(expression, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), Expression.Constant(command.Filter.ToLower()));
            }

            var argParam = expr.Parameters[0];
            var lambda   = Expression.Lambda <Func <T, bool> >(expression, argParam);

            return(lambda);
        }