public static IQueryable <TEntity> Search <TEntity>(this IQueryable <TEntity> source, IEnumerable <KeyValuePair <String, String> > filters)
        {
            if (filters == null || filters.Count() == 0)
            {
                return(source);
            }

            var entity     = Expression.Parameter(typeof(TEntity), "m");
            var conditions = new List <Expression>();

            // Iterate fields
            foreach (var filter in filters)
            {
                try {
                    // Create lambda expression "m.Property.DeepProperty"
                    var property      = ExpressionUtils.GetProperty(entity, filter.Key);
                    var propertyValue = ExpressionUtils.GetNormalized(property);

                    // Create lambda expression "value.ToUpper()"
                    var search      = Expression.Constant(filter.Value.TrimStart('!'));
                    var searchValue = ExpressionUtils.GetNormalized(search);

                    // Create lambda expression "m.PropertyName.ToUpper().Contains(value.ToUpper())"
                    var contains = Expression.Call(propertyValue, "Contains", null, searchValue);

                    // Create lambda expression "m.PropertyName.ToString().ToUpper().Contains(value.ToUpper()) == (true|false)"
                    var condition = Expression.Equal(contains, filter.Value[0] == '!' ? Expression.Constant(false) : Expression.Constant(true));

                    // Add resulter expression o expressions list
                    conditions.Add(condition);
                } catch {
                }
            }

            // Check if have any conditions
            if (conditions.Count > 0)
            {
                // Combine all conditions together
                var predicateBody = conditions.Skip(1).Aggregate(conditions.FirstOrDefault(), (a, b) => Expression.Or(a, b));

                // Create predicate
                var predicate = Expression.Lambda <Func <TEntity, Boolean> >(predicateBody, entity);

                // Apply where clause
                return(source.Where(predicate));
            }

            return(source);
        }
Пример #2
0
        private static Expression GetCondition(Expression entity, KeyValuePair <String, String> filter)
        {
            // Define list of allowed operators
            var operators = new List <String> {
                ">=", "<=", ">", "<", "!?", "!", "?"
            };

            // Initialize value
            var @operator = String.Empty;
            var value     = filter.Value;

            // Iterate allowed operators
            foreach (var entry in operators)
            {
                // Check if value contains operator
                if (value.StartsWith(entry))
                {
                    // Store operator
                    @operator = entry;

                    // Remove operator
                    value = value.TrimStart(entry.ToCharArray());
                }
            }

            // Create lambda expression "m.Property.DeepProperty"
            var property = ExpressionUtils.GetProperty(entity, filter.Key);

            // Try convert value type
            Expression search;

            // Try substitute some keywords
            switch (value.Trim().ToLowerInvariant())
            {
            case "null":
                search = Expression.Constant(null);
                break;

            case "now":
                search = Expression.Constant(DateTime.Now);
                break;

            case "empty":
                search = Expression.Empty();
                break;

            case "default":
                search = Expression.Default(property.Type);
                break;

            default:
                if (property.Type.IsEnum)
                {
                    search = Expression.Constant(Enum.Parse(property.Type, value, true));
                }
                else
                {
                    search = Expression.Constant(Convert.ChangeType(value, property.Type));
                }
                break;
            }

            // Return required expression
            switch (@operator)
            {
            case ">=":
                return(Expression.GreaterThanOrEqual(property, search));

            case "<=":
                return(Expression.LessThanOrEqual(property, search));

            case ">":
                return(Expression.GreaterThan(property, search));

            case "<":
                return(Expression.LessThan(property, search));

            case "!?":
                return(Expression.NotEqual(
                           Expression.Call(
                               ExpressionUtils.GetNormalized(property),
                               "Contains",
                               null,
                               ExpressionUtils.GetNormalized(
                                   Expression.Constant(value)
                                   )
                               ),
                           Expression.Constant(true)
                           ));

            case "!":
                return(Expression.NotEqual(property, search));

            case "?":
                return(Expression.Call(
                           ExpressionUtils.GetNormalized(property),
                           "Contains",
                           null,
                           ExpressionUtils.GetNormalized(Expression.Constant(value))
                           ));

            default:
                return(Expression.Equal(property, search));
            }
        }