Exemplo n.º 1
0
        /// <summary>
        /// Builds a predicate that returns whether an input test object passes the filter rule.
        /// </summary>
        /// <typeparam name="T">The generic type of the input object to test.</typeparam>
        /// <param name="filterRule">The filter rule.</param>
        /// <param name="parsedQuery">The parsed query.</param>
        /// <param name="options">The options to use when building the expression</param>
        /// <returns>A predicate function implementing the filter rule</returns>
        public static Func <T, bool> BuildPredicate <T>(this IFilterRule filterRule, BuildExpressionOptions options, out string parsedQuery)
        {
            var expression = BuildExpressionLambda <T>(filterRule, options, out parsedQuery);

            if (expression == null)
            {
                return(_ => true);
            }

            return(expression.Compile());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Builds an expression lambda for the filter rule.
        /// </summary>
        /// <typeparam name="T">The generic type of the input object to test.</typeparam>
        /// <param name="filterRule">The filter rule.</param>
        /// <param name="parsedQuery">The parsed query.</param>
        /// <param name="options">The options to use when building the expression</param>
        /// <returns>An expression lambda that implements the filter rule</returns>
        public static Expression <Func <T, bool> > BuildExpressionLambda <T>(this IFilterRule filterRule, BuildExpressionOptions options, out string parsedQuery)
        {
            if (filterRule == null)
            {
                parsedQuery = "";
                return(null);
            }

            var pe = Expression.Parameter(typeof(T), "item");

            var expressionTree = BuildExpressionTree(pe, filterRule, options);

            if (expressionTree == null)
            {
                parsedQuery = "";
                return(null);
            }

            parsedQuery = expressionTree.ToString();

            return(Expression.Lambda <Func <T, bool> >(expressionTree, pe));
        }
Exemplo n.º 3
0
        /*
         * private static Expression Between(Type type, object value, Expression propertyExp, BuildExpressionOptions options, string customizedType = null)
         * {
         *  var someValue = GetConstants(type, value, true, options);
         *  var nullCheck = GetNullCheckExpression(propertyExp);
         *  Expression exBelow;
         *  Expression exAbove;
         *
         *  // Handling customized type "anniversarydate" in order to filter on dd/MM formatted dates
         *  if ((propertyExp.Type.Equals(typeof(DateTime)) || propertyExp.Type.Equals(typeof(DateTime?))) && !String.IsNullOrEmpty(customizedType) && customizedType.Equals("anniversarydate"))
         *  {
         *      int startPeriodDay, startPeriodMonth, endPeriodDay, endPeriodMonth;
         *      MethodCallExpression propertyExpToStringMmDd, startPeriodDayToStringMmDd, endPeriodDayToStringMmDd;
         *
         *      if (propertyExp.Type.Equals(typeof(DateTime?)))
         *      {
         *          startPeriodDay = (int)Expression.Lambda(Expression.Property(Expression.Property(Expression.Convert(someValue[0], propertyExp.Type), "Value"), "Day")).Compile().DynamicInvoke();
         *          startPeriodMonth = (int)Expression.Lambda(Expression.Property(Expression.Property(Expression.Convert(someValue[0], propertyExp.Type), "Value"), "Month")).Compile().DynamicInvoke();
         *
         *          endPeriodDay = (int)Expression.Lambda(Expression.Property(Expression.Property(Expression.Convert(someValue[1], propertyExp.Type), "Value"), "Day")).Compile().DynamicInvoke();
         *          endPeriodMonth = (int)Expression.Lambda(Expression.Property(Expression.Property(Expression.Convert(someValue[1], propertyExp.Type), "Value"), "Month")).Compile().DynamicInvoke();
         *
         *          propertyExpToStringMmDd =  Expression.Call(Expression.Property(propertyExp, "Value"), typeof(DateTime).GetMethod("ToString", new[] { typeof(string) }), Expression.Constant("MMdd"));
         *          startPeriodDayToStringMmDd = Expression.Call(someValue[0], typeof(DateTime).GetMethod("ToString", new[] { typeof(string) }), Expression.Constant("MMdd"));
         *          endPeriodDayToStringMmDd = Expression.Call(someValue[1], typeof(DateTime).GetMethod("ToString", new[] { typeof(string) }), Expression.Constant("MMdd"));
         *      }
         *      else
         *      {
         *          startPeriodDay = (int)Expression.Lambda(Expression.Property(Expression.Convert(someValue[0], propertyExp.Type), "Day")).Compile().DynamicInvoke();
         *          startPeriodMonth = (int)Expression.Lambda(Expression.Property(Expression.Convert(someValue[0], propertyExp.Type), "Month")).Compile().DynamicInvoke();
         *
         *          endPeriodDay = (int)Expression.Lambda(Expression.Property(Expression.Convert(someValue[1], propertyExp.Type), "Day")).Compile().DynamicInvoke();
         *          endPeriodMonth = (int)Expression.Lambda(Expression.Property(Expression.Convert(someValue[1], propertyExp.Type), "Month")).Compile().DynamicInvoke();
         *
         *          propertyExpToStringMmDd = Expression.Call(propertyExp, typeof(DateTime).GetMethod("ToString", new[] { typeof(string) }), Expression.Constant("MMdd"));
         *          startPeriodDayToStringMmDd = Expression.Call(Expression.Convert(someValue[0], propertyExp.Type), typeof(DateTime).GetMethod("ToString", new[] { typeof(string) }), Expression.Constant("MMdd"));
         *          endPeriodDayToStringMmDd = Expression.Call(Expression.Convert(someValue[1], propertyExp.Type), typeof(DateTime).GetMethod("ToString", new[] { typeof(string) }), Expression.Constant("MMdd"));
         *      }
         *
         *      var propertyExpMmDd = Expression.Call(typeof(int).GetMethod("Parse", new[] { typeof(string) }), propertyExpToStringMmDd);
         *      var startPeriodDayMmDd = Expression.Call(typeof(int).GetMethod("Parse", new[] { typeof(string) }), startPeriodDayToStringMmDd);
         *      var endPeriodDayMmDd = Expression.Call(typeof(int).GetMethod("Parse", new[] { typeof(string) }), endPeriodDayToStringMmDd);
         *
         *      // Case 1 : end period is on the same year as the start period
         *      if ((endPeriodMonth > startPeriodMonth) || ((endPeriodMonth == startPeriodMonth) && (endPeriodDay >= startPeriodDay)))
         *      {
         *          exBelow = Expression.GreaterThanOrEqual(propertyExpMmDd, startPeriodDayMmDd);
         *          exAbove = Expression.LessThanOrEqual(propertyExpMmDd, endPeriodDayMmDd);
         *      }
         *      // Case 2 : start period and end period are not on the same year
         *      else
         *      {
         *          int startNextYearMmDd = int.Parse(new DateTime(1, 1, 1).ToString("MMdd"));
         *          int endCurrentYearMmDd = int.Parse(new DateTime(1, 12, 31).ToString("MMdd"));
         *
         *          Expression exGreaterThanStartPeriod = Expression.GreaterThanOrEqual(propertyExpMmDd, startPeriodDayMmDd);
         *          Expression exLessThanEndCurrentYear = Expression.LessThanOrEqual(propertyExpMmDd, Expression.Constant(endCurrentYearMmDd));
         *          exBelow = Expression.And(exGreaterThanStartPeriod, exLessThanEndCurrentYear);
         *
         *          Expression exGreaterThanStartNextYear = Expression.GreaterThanOrEqual(propertyExpMmDd, Expression.Constant(startNextYearMmDd));
         *          Expression exLessThanEndPeriod = Expression.LessThanOrEqual(propertyExpMmDd, endPeriodDayMmDd);
         *          exAbove = Expression.And(exGreaterThanStartNextYear, exLessThanEndPeriod);
         *
         *
         *          return Expression.AndAlso(nullCheck, Expression.Or(exBelow, exAbove));
         *      }
         *  }
         *  else
         *  {
         *      exBelow = Expression.GreaterThanOrEqual(propertyExp, Expression.Convert(someValue[0], propertyExp.Type));
         *      exAbove = Expression.LessThanOrEqual(propertyExp, Expression.Convert(someValue[1], propertyExp.Type));
         *  }
         *
         *  return Expression.AndAlso(nullCheck, Expression.And(exBelow, exAbove));
         * }
         */
        #endregion

        private static Expression NotBetween(Type type, object value, Expression propertyExp, BuildExpressionOptions options)
        {
            return(Expression.Not(Between(type, value, propertyExp, options)));
        }
Exemplo n.º 4
0
        private static Expression GreaterThan(Type type, object value, Expression propertyExp, BuildExpressionOptions options, Expression rightPropertyExp = null)
        {
            if (rightPropertyExp != null)
            {
                return(Expression.GreaterThan(propertyExp, rightPropertyExp));
            }

            var someValue = GetConstants(type, value, false, options).First();



            Expression exOut = Expression.GreaterThan(propertyExp, Expression.Convert(someValue, propertyExp.Type));


            return(exOut);
        }
Exemplo n.º 5
0
 private static Expression NotEquals(Type type, object value, Expression propertyExp, BuildExpressionOptions options, string customizedType = null)
 {
     return(Expression.Not(Equals(type, value, propertyExp, options, customizedType)));
 }
Exemplo n.º 6
0
        private static Expression GreaterThanOrEqual(Type type, object value, Expression propertyExp, BuildExpressionOptions options)
        {
            var someValue = GetConstants(type, value, false, options).First();

            Expression exOut = Expression.GreaterThanOrEqual(propertyExp, Expression.Convert(someValue, propertyExp.Type));


            return(exOut);
        }
Exemplo n.º 7
0
        private static Expression BuildOperatorExpression(Expression propertyExp, IFilterRule rule, BuildExpressionOptions options, Type type)
        {
            Expression expression;
            string     oper = rule.Operator.ToLower();

            switch (oper)
            {
            case "in":
                expression = In(type, rule.Value, propertyExp, options);
                break;

            case "not_in":
                expression = NotIn(type, rule.Value, propertyExp, options);
                break;

            case "equal":
                expression = Equals(type, rule.Value, propertyExp, options);
                break;

            case "not_equal":
                expression = NotEquals(type, rule.Value, propertyExp, options);
                break;

            case "between":
                expression = Between(type, rule.Value, propertyExp, options);
                break;

            case "not_between":
                expression = NotBetween(type, rule.Value, propertyExp, options);
                break;

            case "less":
                expression = LessThan(type, rule.Value, propertyExp, options);
                break;

            case "less_or_equal":
                expression = LessThanOrEqual(type, rule.Value, propertyExp, options);
                break;

            case "greater":
                expression = GreaterThan(type, rule.Value, propertyExp, options);
                break;

            case "greater_or_equal":
                expression = GreaterThanOrEqual(type, rule.Value, propertyExp, options);
                break;

            case "begins_with":
                expression = BeginsWith(type, rule.Value, propertyExp);
                break;

            case "not_begins_with":
                expression = NotBeginsWith(type, rule.Value, propertyExp);
                break;

            case "contains":
                expression = Contains(type, rule.Value, propertyExp);
                break;

            case "not_contains":
                expression = NotContains(type, rule.Value, propertyExp);
                break;

            case "ends_with":
                expression = EndsWith(type, rule.Value, propertyExp);
                break;

            case "not_ends_with":
                expression = NotEndsWith(type, rule.Value, propertyExp);
                break;

            case "is_empty":
                expression = IsEmpty(propertyExp);
                break;

            case "is_not_empty":
                expression = IsNotEmpty(propertyExp);
                break;

            case "is_null":
                expression = IsNull(propertyExp);
                break;

            case "is_not_null":
                expression = IsNotNull(propertyExp);
                break;

            default:
                //custom operators support
                var operators = options.Operators;
                if (operators != null && operators.Count() > 0)
                {
                    var customOperator = (from p in operators where p.Operator.ToLower() == oper select p).FirstOrDefault();
                    if (customOperator != null)
                    {
                        return(customOperator.GetExpression(type, rule, propertyExp, options));
                    }
                }

                throw new Exception($"Unknown expression operator: {rule.Operator}");
            }

            return(expression);
        }
Exemplo n.º 8
0
        private static Expression BuildOperatorExpression(Expression propertyExp, IFilterRule rule, BuildExpressionOptions options, Type type)
        {
            Expression expression;

            switch (rule.Operator.ToLower())
            {
            case "in":
                expression = In(type, rule.Value, propertyExp, options, rule.Type);
                break;

            case "not_in":
                expression = NotIn(type, rule.Value, propertyExp, options, rule.Type);
                break;

            case "equal":
                expression = Equals(type, rule.Value, propertyExp, options, rule.Type);
                break;

            case "not_equal":
                expression = NotEquals(type, rule.Value, propertyExp, options, rule.Type);
                break;

            case "between":
                expression = Between(type, rule.Value, propertyExp, options);
                break;

            case "not_between":
                expression = NotBetween(type, rule.Value, propertyExp, options);
                break;

            case "less":
                expression = LessThan(type, rule.Value, propertyExp, options);
                break;

            case "less_or_equal":
                expression = LessThanOrEqual(type, rule.Value, propertyExp, options);
                break;

            case "greater":
                expression = GreaterThan(type, rule.Value, propertyExp, options);
                break;

            case "greater_or_equal":
                expression = GreaterThanOrEqual(type, rule.Value, propertyExp, options);
                break;

            case "begins_with":
                expression = BeginsWith(type, rule.Value, propertyExp);
                break;

            case "not_begins_with":
                expression = NotBeginsWith(type, rule.Value, propertyExp);
                break;

            case "contains":
                expression = Contains(type, rule.Value, propertyExp);
                break;

            case "not_contains":
                expression = NotContains(type, rule.Value, propertyExp);
                break;

            case "ends_with":
                expression = EndsWith(type, rule.Value, propertyExp);
                break;

            case "not_ends_with":
                expression = NotEndsWith(type, rule.Value, propertyExp);
                break;

            case "is_empty":
                expression = IsEmpty(propertyExp);
                break;

            case "is_not_empty":
                expression = IsNotEmpty(propertyExp);
                break;

            case "is_null":
                expression = IsNull(propertyExp);
                break;

            case "is_not_null":
                expression = IsNotNull(propertyExp);
                break;

            case "is_null_or_empty":
                expression = IsNullOrEmpty(propertyExp);
                break;

            case "is_not_null_and_not_empty":
                expression = IsNotNullAndNotEmpty(propertyExp);
                break;

            default:
                throw new Exception($"Unknown expression operator: {rule.Operator}");
            }

            return(expression);
        }
Exemplo n.º 9
0
 private static Expression NotIn(Type type, string value, Expression propertyExp, BuildExpressionOptions options)
 {
     return(Expression.Not(In(type, value, propertyExp, options)));
 }
        private static Expression BuildExpressionTree(ParameterExpression pe, IFilterRule rule, BuildExpressionOptions options)
        {
            if (rule.Rules != null && rule.Rules.Any())
            {
                var expressions =
                    rule.Rules.Select(childRule => BuildExpressionTree(pe, childRule, options))
                    .Where(expression => expression != null)
                    .ToList();

                var expressionTree = expressions.First();

                var counter = 1;
                while (counter < expressions.Count)
                {
                    expressionTree = rule.Condition.ToLower() == "or"
                        ? Expression.Or(expressionTree, expressions[counter])
                        : Expression.And(expressionTree, expressions[counter]);
                    counter++;
                }

                return(expressionTree);
            }
            if (rule.Field != null)
            {
                Type type;

                switch (rule.Type)
                {
                case "integer":
                    type = typeof(int);
                    break;

                case "double":
                    type = typeof(double);
                    break;

                case "string":
                    type = typeof(string);
                    break;

                case "date":
                case "datetime":
                    type = typeof(DateTime);
                    break;

                case "boolean":
                    type = typeof(bool);
                    break;

                default:
                    throw new Exception($"Unexpected data type {rule.Type}");
                }

                Expression propertyExp = null;
                if (options.UseIndexedProperty)
                {
                    propertyExp = Expression.Property(pe, options.IndexedPropertyName, Expression.Constant(rule.Field));
                }
                else
                {
                    var propertyList = rule.Field.Split('.').ToList();
                    if (propertyList.Count() > 1)
                    {
                        propertyExp = Expression.Property(pe, propertyList.First());
                        foreach (var prop in propertyList.Skip(1))
                        {
                            propertyExp = Expression.Property(propertyExp, prop);
                        }
                    }
                    else
                    {
                        propertyExp = Expression.Property(pe, rule.Field);
                    }
                }

                Expression expression;

                switch (rule.Operator.ToLower())
                {
                case "in":
                    expression = In(type, rule.Value, propertyExp, options);
                    break;

                case "not_in":
                    expression = NotIn(type, rule.Value, propertyExp, options);
                    break;

                case "equal":
                    expression = Equals(type, rule.Value, propertyExp, options);
                    break;

                case "not_equal":
                    expression = NotEquals(type, rule.Value, propertyExp, options);
                    break;

                case "between":
                    expression = Between(type, rule.Value, propertyExp, options);
                    break;

                case "not_between":
                    expression = NotBetween(type, rule.Value, propertyExp, options);
                    break;

                case "less":
                    expression = LessThan(type, rule.Value, propertyExp, options);
                    break;

                case "less_or_equal":
                    expression = LessThanOrEqual(type, rule.Value, propertyExp, options);
                    break;

                case "greater":
                    expression = GreaterThan(type, rule.Value, propertyExp, options);
                    break;

                case "greater_or_equal":
                    expression = GreaterThanOrEqual(type, rule.Value, propertyExp, options);
                    break;

                case "begins_with":
                    expression = BeginsWith(type, rule.Value, propertyExp);
                    break;

                case "not_begins_with":
                    expression = NotBeginsWith(type, rule.Value, propertyExp);
                    break;

                case "contains":
                    expression = Contains(type, rule.Value, propertyExp);
                    break;

                case "not_contains":
                    expression = NotContains(type, rule.Value, propertyExp);
                    break;

                case "ends_with":
                    expression = EndsWith(type, rule.Value, propertyExp);
                    break;

                case "not_ends_with":
                    expression = NotEndsWith(type, rule.Value, propertyExp);
                    break;

                case "is_empty":
                    expression = IsEmpty(propertyExp);
                    break;

                case "is_not_empty":
                    expression = IsNotEmpty(propertyExp);
                    break;

                case "is_null":
                    expression = IsNull(propertyExp);
                    break;

                case "is_not_null":
                    expression = IsNotNull(propertyExp);
                    break;

                default:
                    throw new Exception($"Unknown expression operator: {rule.Operator}");
                }

                return(expression);
            }
            return(null);
        }
Exemplo n.º 11
0
        private static Expression LessThan(Type type, string value, Expression propertyExp, BuildExpressionOptions options)
        {
            var someValue = GetConstants(type, value, false, options).First();

            Expression exOut = Expression.LessThan(propertyExp, Expression.Convert(someValue, propertyExp.Type));


            return(exOut);
        }
Exemplo n.º 12
0
 private static List <ConstantExpression> GetConstants(Type type, string value, bool isCollection, BuildExpressionOptions options)
 {
     if (type == typeof(DateTime) && (options.ParseDatesAsUtc || ParseDatesAsUtc))
     {
         DateTime tDate;
         if (isCollection)
         {
             var vals =
                 value.Split(new[] { ",", "[", "]", "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
                 .Where(p => !string.IsNullOrWhiteSpace(p))
                 .Select(
                     p =>
                     DateTime.TryParse(p.Trim(), options.CultureInfo,
                                       DateTimeStyles.AdjustToUniversal, out tDate)
                                 ? (DateTime?)
                     tDate
                                 : null).Select(p =>
                                                Expression.Constant(p, type));
             return(vals.ToList());
         }
         else
         {
             return(new List <ConstantExpression>()
             {
                 Expression.Constant(DateTime.TryParse(value.Trim(), options.CultureInfo,
                                                       DateTimeStyles.AdjustToUniversal, out tDate)
                     ? (DateTime?)
                                     tDate
                     : null)
             });
         }
     }
     else
     {
         if (isCollection)
         {
             var tc = TypeDescriptor.GetConverter(type);
             if (type == typeof(string))
             {
                 var bracketSplit = value.Split(new[] { "[", "]" }, StringSplitOptions.RemoveEmptyEntries);
                 var vals         =
                     bracketSplit.SelectMany(v => v.Split(new[] { ",", "\r\n" }, StringSplitOptions.None))
                     .Select(p => tc.ConvertFromString(null, options.CultureInfo, p.Trim())).Select(p =>
                                                                                                    Expression.Constant(p, type));
                 return(vals.Distinct().ToList());
             }
             else
             {
                 var vals =
                     value.Split(new[] { ",", "[", "]", "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
                     .Where(p => !string.IsNullOrWhiteSpace(p))
                     .Select(p => tc.ConvertFromString(null, options.CultureInfo, p.Trim())).Select(p =>
                                                                                                    Expression.Constant(p, type));
                 return(vals.ToList());
             }
         }
         else
         {
             var tc = TypeDescriptor.GetConverter(type);
             return(new List <ConstantExpression>()
             {
                 Expression.Constant(tc.ConvertFromString(null, options.CultureInfo, value.Trim()))
             });
         }
     }
 }
Exemplo n.º 13
0
        private static Expression BuildElementAccessExpression(Expression expression, IEnumerator <string> propertyCollectionEnumerator, IFilterRule rule, BuildExpressionOptions options, Type type)
        {
            var propertyName = propertyCollectionEnumerator.Current;

            var leftBraceIndex  = propertyName.IndexOf("[");
            var rightBraceIndex = propertyName.IndexOf("]");

            if (leftBraceIndex > -1)
            {
                propertyName = propertyName.Substring(0, leftBraceIndex);
            }

            var propertyInfo       = expression.Type.GetProperty(propertyName);
            var propertyExpression = Expression.Property(expression, propertyInfo);

            var propertyType = propertyInfo.PropertyType;
            var dictionary   = propertyType.GetInterface("IDictionary`2");

            Type[] dictionaryTypes     = dictionary.GetGenericArguments();
            Type   dictionaryKeyType   = dictionaryTypes[0];
            Type   dictionaryValueType = dictionaryTypes[1];

            if (dictionaryKeyType != typeof(string))
            {
                throw new NotSupportedException("Only Dictionaries with string keys are supported at present.");
            }

            var dictionaryKeyValue = propertyCollectionEnumerator.Current.Substring(leftBraceIndex + 2, propertyCollectionEnumerator.Current.Length - leftBraceIndex - 4);

            PropertyInfo indexerProperty    = dictionary.GetProperty("Item");
            var          dictionaryKeyConst = Expression.Constant(dictionaryKeyValue);

            var indexExpression = Expression.MakeIndex(propertyExpression, indexerProperty, new[] { dictionaryKeyConst });

            return(indexExpression);
        }
Exemplo n.º 14
0
        private static Expression BuildExpressionTree(ParameterExpression pe, IFilterRule rule, BuildExpressionOptions options)
        {
            if (rule.Rules != null && rule.Rules.Any())
            {
                var expressions =
                    rule.Rules.Select(childRule => BuildExpressionTree(pe, childRule, options))
                    .Where(expression => expression != null)
                    .ToList();

                var expressionTree = expressions.First();

                var counter = 1;
                while (counter < expressions.Count)
                {
                    expressionTree = rule.Condition.ToLower() == "or"
                        ? Expression.Or(expressionTree, expressions[counter])
                        : Expression.And(expressionTree, expressions[counter]);
                    counter++;
                }

                return(expressionTree);
            }
            if (rule.Field != null)
            {
                Type type;

                switch (rule.Type)
                {
                case "integer":
                    type = typeof(int);
                    break;

                case "double":
                    type = typeof(double);
                    break;

                case "string":
                    type = typeof(string);
                    break;

                case "date":
                case "datetime":
                case "anniversarydate":
                    type = typeof(DateTime);
                    break;

                case "boolean":
                    type = typeof(bool);
                    break;

                default:
                    throw new Exception($"Unexpected data type {rule.Type}");
                }

                if (options.UseIndexedProperty)
                {
                    var propertyExp = Expression.Property(pe, options.IndexedPropertyName, Expression.Constant(rule.Field));
                    return(BuildOperatorExpression(propertyExp, rule, options, type));
                }
                else
                {
                    var propertyList = rule.Field.Split('.');
                    if (propertyList.Length > 1)
                    {
                        var propertyCollectionEnumerator = propertyList.AsEnumerable().GetEnumerator();
                        return(BuildNestedExpression(pe, propertyCollectionEnumerator, rule, options, type));
                    }
                    else
                    {
                        var propertyExp = Expression.Property(pe, rule.Field);
                        return(BuildOperatorExpression(propertyExp, rule, options, type));
                    }
                }
            }
            return(null);
        }
Exemplo n.º 15
0
        private static Expression Equals(Type type, object value, Expression propertyExp, BuildExpressionOptions options)
        {
            Expression someValue = GetConstants(type, value, false, options).First();

            Expression exOut;

            if (type == typeof(string))
            {
                var nullCheck = GetNullCheckExpression(propertyExp);

                exOut     = Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                someValue = Expression.Call(someValue, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                exOut     = Expression.AndAlso(nullCheck, Expression.Equal(exOut, someValue));
            }
            else
            {
                exOut = Expression.Equal(propertyExp, Expression.Convert(someValue, propertyExp.Type));
            }

            return(exOut);
        }
Exemplo n.º 16
0
        private static Expression BuildNestedExpression(Expression expression, IEnumerator <string> propertyCollectionEnumerator, IFilterRule rule, BuildExpressionOptions options, Type type)
        {
            while (propertyCollectionEnumerator.MoveNext())
            {
                var propertyName = propertyCollectionEnumerator.Current;
                var property     = expression.Type.GetProperty(propertyName);
                expression = Expression.Property(expression, property);

                var propertyType = property.PropertyType;
                var enumerable   = propertyType.GetInterface("IEnumerable`1");
                if (propertyType != typeof(string) && enumerable != null)
                {
                    var elementType         = enumerable.GetGenericArguments()[0];
                    var predicateFnType     = typeof(Func <,>).MakeGenericType(elementType, typeof(bool));
                    var parameterExpression = Expression.Parameter(elementType);

                    Expression body      = BuildNestedExpression(parameterExpression, propertyCollectionEnumerator, rule, options, type);
                    var        predicate = Expression.Lambda(predicateFnType, body, parameterExpression);

                    var queryable = Expression.Call(typeof(Queryable), "AsQueryable", new[] { elementType }, expression);

                    return(Expression.Call(
                               typeof(Queryable),
                               "Any",
                               new[] { elementType },
                               queryable,
                               predicate
                               ));
                }
            }

            return(BuildOperatorExpression(expression, rule, options, type));
        }
Exemplo n.º 17
0
        private static Expression In(Type type, object value, Expression propertyExp, BuildExpressionOptions options)
        {
            var someValues = GetConstants(type, value, true, options);

            var nullCheck = GetNullCheckExpression(propertyExp);

            if (IsGenericList(propertyExp.Type))
            {
                var        genericType = propertyExp.Type.GetGenericArguments().First();
                var        method      = propertyExp.Type.GetMethod("Contains", new[] { genericType });
                Expression exOut;

                if (someValues.Count > 1)
                {
                    exOut = Expression.Call(propertyExp, method, Expression.Convert(someValues[0], genericType));
                    var counter = 1;
                    while (counter < someValues.Count)
                    {
                        exOut = Expression.Or(exOut,
                                              Expression.Call(propertyExp, method, Expression.Convert(someValues[counter], genericType)));
                        counter++;
                    }
                }
                else
                {
                    exOut = Expression.Call(propertyExp, method, Expression.Convert(someValues.First(), genericType));
                }


                return(Expression.AndAlso(nullCheck, exOut));
            }
            else
            {
                Expression exOut;

                if (someValues.Count > 1)
                {
                    if (type == typeof(string))
                    {
                        exOut = Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        var somevalue = Expression.Call(someValues[0], typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        exOut = Expression.Equal(exOut, somevalue);
                        var counter = 1;
                        while (counter < someValues.Count)
                        {
                            var nextvalue = Expression.Call(someValues[counter], typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                            exOut = Expression.Or(exOut,
                                                  Expression.Equal(
                                                      Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes)),
                                                      nextvalue));
                            counter++;
                        }
                    }
                    else
                    {
                        exOut = Expression.Equal(propertyExp, Expression.Convert(someValues[0], propertyExp.Type));
                        var counter = 1;
                        while (counter < someValues.Count)
                        {
                            exOut = Expression.Or(exOut,
                                                  Expression.Equal(propertyExp, Expression.Convert(someValues[counter], propertyExp.Type)));
                            counter++;
                        }
                    }
                }
                else
                {
                    if (type == typeof(string))
                    {
                        exOut = Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        var somevalue = Expression.Call(someValues.First(), typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        exOut = Expression.Equal(exOut, somevalue);
                    }
                    else
                    {
                        exOut = Expression.Equal(propertyExp, Expression.Convert(someValues.First(), propertyExp.Type));
                    }
                }


                return(Expression.AndAlso(nullCheck, exOut));
            }
        }
Exemplo n.º 18
0
        private static List <ConstantExpression> GetConstants(Type type, object value, bool isCollection, BuildExpressionOptions options)
        {
            if (type == typeof(DateTime) && (options.ParseDatesAsUtc || ParseDatesAsUtc))
            {
                DateTime tDate;
                if (isCollection)
                {
                    if (!(value is string) && value is IEnumerable list)
                    {
                        var constants = new List <ConstantExpression>();

                        foreach (object item in list)
                        {
                            var date = DateTime.TryParse(item.ToString().Trim(), options.CultureInfo,
                                                         DateTimeStyles.AdjustToUniversal, out tDate)
                                            ? (DateTime?)
                                       tDate
                                            : null;
                            constants.Add(Expression.Constant(date, type));
                        }

                        return(constants);
                    }
                    else
                    {
                        var vals =
                            value.ToString().Split(new[] { ",", "[", "]", "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
                            .Where(p => !string.IsNullOrWhiteSpace(p))
                            .Select(
                                p =>
                                DateTime.TryParse(p.Trim(), options.CultureInfo,
                                                  DateTimeStyles.AdjustToUniversal, out tDate)
                                            ? (DateTime?)
                                tDate
                                            : null).Select(p =>
                                                           Expression.Constant(p, type));
                        return(vals.ToList());
                    }
                }
                else
                {
                    if (value is Array items)
                    {
                        value = items.GetValue(0);
                    }
                    return(new List <ConstantExpression>()
                    {
                        Expression.Constant(DateTime.TryParse(value.ToString().Trim(), options.CultureInfo,
                                                              DateTimeStyles.AdjustToUniversal, out tDate)
                            ? (DateTime?)
                                            tDate
                            : null)
                    });
                }
            }
            else
            {
                if (isCollection)
                {
                    var tc = TypeDescriptor.GetConverter(type);
                    if (type == typeof(string))
                    {
                        if (!(value is string) && value is IEnumerable list)
                        {
                            var expressions = new List <ConstantExpression>();

                            foreach (object item in list)
                            {
                                expressions.Add(Expression.Constant(tc.ConvertFromString(item.ToString()), type));
                            }

                            return(expressions);
                        }
                        else
                        {
                            var bracketSplit = value.ToString().Split(new[] { "[", "]" }, StringSplitOptions.RemoveEmptyEntries);
                            var vals         =
                                bracketSplit.SelectMany(v => v.Split(new[] { ",", "\r\n" }, StringSplitOptions.None))
                                .Select(p => tc.ConvertFromString(null, options.CultureInfo, p.Trim())).Select(p =>
                                                                                                               Expression.Constant(p, type));
                            return(vals.Distinct().ToList());
                        }
                    }
                    else
                    {
                        if (!(value is string) && value is IEnumerable list)
                        {
                            var expressions = new List <ConstantExpression>();

                            foreach (object item in list)
                            {
                                expressions.Add(Expression.Constant(tc.ConvertFromString(item.ToString()), type));
                            }

                            return(expressions);
                        }
                        else
                        {
                            var vals =
                                value.ToString().Split(new[] { ",", "[", "]", "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
                                .Where(p => !string.IsNullOrWhiteSpace(p))
                                .Select(p => tc.ConvertFromString(null, options.CultureInfo, p.Trim())).Select(p =>
                                                                                                               Expression.Constant(p, type));
                            return(vals.ToList());
                        }
                    }
                }
                else
                {
                    var tc = TypeDescriptor.GetConverter(type);
                    if (value is Array items)
                    {
                        value = items.GetValue(0);
                    }

                    return(new List <ConstantExpression>
                    {
                        Expression.Constant(tc.ConvertFromString(null, options.CultureInfo, value.ToString().Trim()))
                    });
                }
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Gets the filtered collection after applying the provided filter rules.
        /// Returns the string representation for diagnostic purposes.
        /// </summary>
        /// <typeparam name="T">The generic type.</typeparam>
        /// <param name="queryable">The queryable.</param>
        /// <param name="filterRule">The filter rule.</param>
        /// <param name="options">The options to use when building the expression</param>
        /// <returns>Filtered IQueryable.</returns>
        public static IQueryable <T> BuildQuery <T>(this IQueryable <T> queryable, IFilterRule filterRule, BuildExpressionOptions options)
        {
            string parsedQuery;

            return(BuildQuery(queryable, filterRule, options, out parsedQuery));
        }
Exemplo n.º 20
0
        private static Expression Equals(Type type, object value, Expression propertyExp, BuildExpressionOptions options, string customizedType = null)
        {
            Expression someValue = GetConstants(type, value, false, options).First();

            Expression exOut;

            if (type == typeof(string))
            {
                var nullCheck = GetNullCheckExpression(propertyExp);

                exOut     = Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                someValue = Expression.Call(someValue, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                exOut     = Expression.AndAlso(nullCheck, Expression.Equal(exOut, someValue));
            }
            // Handling customized type "anniversarydate" in order to filter on dd/MM formatted dates
            else if ((propertyExp.Type.Equals(typeof(DateTime)) || propertyExp.Type.Equals(typeof(DateTime?))) && !String.IsNullOrEmpty(customizedType) && customizedType.Equals("anniversarydate"))
            {
                Expression exDayEqual;
                Expression exMonthEqual;
                if (propertyExp.Type.Equals(typeof(DateTime?)))
                {
                    exDayEqual   = Expression.Equal(Expression.Property(Expression.Property(propertyExp, "Value"), "Day"), Expression.Property(Expression.Property(Expression.Convert(someValue, propertyExp.Type), "Value"), "Day"));
                    exMonthEqual = Expression.Equal(Expression.Property(Expression.Property(propertyExp, "Value"), "Month"), Expression.Property(Expression.Property(Expression.Convert(someValue, propertyExp.Type), "Value"), "Month"));
                }
                else
                {
                    exDayEqual   = Expression.Equal(Expression.Property(propertyExp, "Day"), Expression.Property(Expression.Convert(someValue, propertyExp.Type), "Day"));
                    exMonthEqual = Expression.Equal(Expression.Property(propertyExp, "Month"), Expression.Property(Expression.Convert(someValue, propertyExp.Type), "Month"));
                }

                exOut = Expression.And(exDayEqual, exMonthEqual);
            }
            else
            {
                exOut = Expression.Equal(propertyExp, Expression.Convert(someValue, propertyExp.Type));
            }

            return(exOut);
        }
Exemplo n.º 21
0
        /// <summary>
        /// Gets the filtered collection after applying the provided filter rules.
        /// Returns the string representation for diagnostic purposes.
        /// </summary>
        /// <typeparam name="T">The generic type.</typeparam>
        /// <param name="queryable">The queryable.</param>
        /// <param name="filterRule">The filter rule.</param>
        /// <param name="options">The options to use when building the expression</param>
        /// <param name="parsedQuery">The parsed query.</param>
        /// <returns>Filtered IQueryable.</returns>
        public static IQueryable <T> BuildQuery <T>(this IQueryable <T> queryable, IFilterRule filterRule, BuildExpressionOptions options, out string parsedQuery)
        {
            var expression = BuildExpressionLambda <T>(filterRule, options, out parsedQuery);

            if (expression == null)
            {
                return(queryable);
            }

            var whereCallExpression = Expression.Call(
                typeof(Queryable),
                "Where",
                new[] { queryable.ElementType },
                queryable.Expression,
                expression);

            var filteredResults = queryable.Provider.CreateQuery <T>(whereCallExpression);

            return(filteredResults);
        }
Exemplo n.º 22
0
        private static Expression Between(Type type, object value, Expression propertyExp, BuildExpressionOptions options)
        {
            var someValue = GetConstants(type, value, true, options);


            Expression exBelow = Expression.GreaterThanOrEqual(propertyExp, Expression.Convert(someValue[0], propertyExp.Type));
            Expression exAbove = Expression.LessThanOrEqual(propertyExp, Expression.Convert(someValue[1], propertyExp.Type));

            return(Expression.And(exBelow, exAbove));
        }
Exemplo n.º 23
0
        /// <summary>
        /// Builds a predicate that returns whether an input test object passes the filter rule.
        /// </summary>
        /// <typeparam name="T">The generic type of the input object to test.</typeparam>
        /// <param name="filterRule">The filter rule.</param>
        /// <param name="options">The options to use when building the expression</param>
        /// <returns>A predicate function implementing the filter rule</returns>
        public static Func <T, bool> BuildPredicate <T>(this IFilterRule filterRule, BuildExpressionOptions options)
        {
            string parsedQuery;

            return(BuildPredicate <T>(filterRule, options, out parsedQuery));
        }
Exemplo n.º 24
0
        private static Expression In(Type type, object value, Expression propertyExp, BuildExpressionOptions options, string customizedType = null)
        {
            var someValues = GetConstants(type, value, true, options);

            var nullCheck = GetNullCheckExpression(propertyExp);

            if (IsGenericList(propertyExp.Type))
            {
                var        genericType = propertyExp.Type.GetGenericArguments().First();
                var        method      = propertyExp.Type.GetMethod("Contains", new[] { genericType });
                Expression exOut;

                if (someValues.Count > 1)
                {
                    exOut = Expression.Call(propertyExp, method, Expression.Convert(someValues[0], genericType));
                    var counter = 1;
                    while (counter < someValues.Count)
                    {
                        exOut = Expression.Or(exOut,
                                              Expression.Call(propertyExp, method, Expression.Convert(someValues[counter], genericType)));
                        counter++;
                    }
                }
                else
                {
                    exOut = Expression.Call(propertyExp, method, Expression.Convert(someValues.First(), genericType));
                }


                return(Expression.AndAlso(nullCheck, exOut));
            }
            else
            {
                Expression exOut;

                if (someValues.Count > 1)
                {
                    if (type == typeof(string))
                    {
                        exOut = Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        var somevalue = Expression.Call(someValues[0], typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        exOut = Expression.Equal(exOut, somevalue);
                        var counter = 1;
                        while (counter < someValues.Count)
                        {
                            var nextvalue = Expression.Call(someValues[counter], typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                            exOut = Expression.Or(exOut,
                                                  Expression.Equal(
                                                      Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes)),
                                                      nextvalue));
                            counter++;
                        }
                    }
                    // Handling customized type "anniversarydate" in order to filter on dd/MM formatted dates
                    else if ((propertyExp.Type.Equals(typeof(DateTime)) || propertyExp.Type.Equals(typeof(DateTime?))) && !String.IsNullOrEmpty(customizedType) && customizedType.Equals("anniversarydate"))
                    {
                        Expression exDayEqual;
                        Expression exMonthEqual;

                        if (propertyExp.Type.Equals(typeof(DateTime?)))
                        {
                            exDayEqual = Expression.Equal(
                                Expression.Property(Expression.Property(propertyExp, "Value"), "Day"),
                                Expression.Property(Expression.Property(Expression.Convert(someValues[0], propertyExp.Type), "Value"), "Day"));
                            exMonthEqual = Expression.Equal(
                                Expression.Property(Expression.Property(propertyExp, "Value"), "Month"),
                                Expression.Property(Expression.Property(Expression.Convert(someValues[0], propertyExp.Type), "Value"), "Month"));
                        }
                        else
                        {
                            exDayEqual   = Expression.Equal(Expression.Property(propertyExp, "Day"), Expression.Property(Expression.Convert(someValues[0], propertyExp.Type), "Day"));
                            exMonthEqual = Expression.Equal(Expression.Property(propertyExp, "Month"), Expression.Property(Expression.Convert(someValues[0], propertyExp.Type), "Month"));
                        }

                        exOut = Expression.And(exDayEqual, exMonthEqual);

                        var counter = 1;
                        while (counter < someValues.Count)
                        {
                            if (propertyExp.Type.Equals(typeof(DateTime?)))
                            {
                                exDayEqual = Expression.Equal(
                                    Expression.Property(Expression.Property(propertyExp, "Value"), "Day"),
                                    Expression.Property(Expression.Property(Expression.Convert(someValues[counter], propertyExp.Type), "Value"), "Day"));
                                exMonthEqual = Expression.Equal(
                                    Expression.Property(Expression.Property(propertyExp, "Value"), "Month"),
                                    Expression.Property(Expression.Property(Expression.Convert(someValues[counter], propertyExp.Type), "Value"), "Month"));
                            }
                            else
                            {
                                exDayEqual   = Expression.Equal(Expression.Property(propertyExp, "Day"), Expression.Property(Expression.Convert(someValues[counter], propertyExp.Type), "Day"));
                                exMonthEqual = Expression.Equal(Expression.Property(propertyExp, "Month"), Expression.Property(Expression.Convert(someValues[counter], propertyExp.Type), "Month"));
                            }
                            exOut = Expression.Or(exOut, Expression.And(exDayEqual, exMonthEqual));
                            counter++;
                        }
                    }
                    else
                    {
                        exOut = Expression.Equal(propertyExp, Expression.Convert(someValues[0], propertyExp.Type));
                        var counter = 1;
                        while (counter < someValues.Count)
                        {
                            exOut = Expression.Or(exOut,
                                                  Expression.Equal(propertyExp, Expression.Convert(someValues[counter], propertyExp.Type)));
                            counter++;
                        }
                    }
                }
                else
                {
                    if (type == typeof(string))
                    {
                        exOut = Expression.Call(propertyExp, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        var somevalue = Expression.Call(someValues.First(), typeof(string).GetMethod("ToLower", Type.EmptyTypes));
                        exOut = Expression.Equal(exOut, somevalue);
                    }
                    // Handling customized type "anniversarydate" in order to filter on dd/MM formatted dates
                    else if ((propertyExp.Type.Equals(typeof(DateTime)) || propertyExp.Type.Equals(typeof(DateTime?))) && !String.IsNullOrEmpty(customizedType) && customizedType.Equals("anniversarydate"))
                    {
                        Expression exDayEqual;
                        Expression exMonthEqual;

                        if (propertyExp.Type.Equals(typeof(DateTime?)))
                        {
                            exDayEqual = Expression.Equal(
                                Expression.Property(Expression.Property(propertyExp, "Value"), "Day"),
                                Expression.Property(Expression.Property(Expression.Convert(someValues.First(), propertyExp.Type), "Value"), "Day"));
                            exMonthEqual = Expression.Equal(
                                Expression.Property(Expression.Property(propertyExp, "Value"), "Month"),
                                Expression.Property(Expression.Property(Expression.Convert(someValues.First(), propertyExp.Type), "Value"), "Month"));
                        }
                        else
                        {
                            exDayEqual   = Expression.Equal(Expression.Property(propertyExp, "Day"), Expression.Property(Expression.Convert(someValues.First(), propertyExp.Type), "Day"));
                            exMonthEqual = Expression.Equal(Expression.Property(propertyExp, "Month"), Expression.Property(Expression.Convert(someValues.First(), propertyExp.Type), "Month"));
                        }

                        exOut = Expression.And(exDayEqual, exMonthEqual);
                    }
                    else
                    {
                        exOut = Expression.Equal(propertyExp, Expression.Convert(someValues.First(), propertyExp.Type));
                    }
                }


                return(Expression.AndAlso(nullCheck, exOut));
            }
        }
Exemplo n.º 25
0
 private static Expression NotEquals(Type type, object value, Expression propertyExp, BuildExpressionOptions options, Expression rightPropertyExp = null)
 {
     return(Expression.Not(Equals(type, value, propertyExp, options, rightPropertyExp)));
 }