Esempio n. 1
0
        private static Expression BuildExpressionTree(ParameterExpression pe, FilterRule rule, bool useIndexedProperty = false, string indexedPropertyName = null)
        {
            if (rule.Rules != null && rule.Rules.Any())
            {
                var expressions =
                    rule.Rules.Select(childRule => BuildExpressionTree(pe, childRule, useIndexedProperty, indexedPropertyName))
                    .Where(exp => exp != 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 (string.IsNullOrEmpty(rule.Field))
            {
                throw new Exception("属性未设置");
            }

            if (string.IsNullOrEmpty(rule.Operator))
            {
                throw new Exception($"属性【{rule.Field}】运算符未设置");
            }

            Expression propertyExp = null;

            if (useIndexedProperty)
            {
                propertyExp = Expression.Property(pe, indexedPropertyName, Expression.Constant(rule.Field));
            }
            else
            {
                // QT 扩展,支持复杂属性 obj.Foo.Boo
                if (string.IsNullOrEmpty(rule.Table))
                {
                    if (pe.Type.GetProperty(rule.Field) == null)
                    {
                        throw new Exception(string.Format("对象【{0}】属性【{1}】不存在", pe.Type.Name, rule.Field));
                    }
                    propertyExp = Expression.Property(pe, rule.Field);
                }
                else
                {
                    propertyExp = Expression.Property(pe, rule.Table);

                    if (propertyExp.Type.GetProperty(rule.Field) == null)
                    {
                        throw new Exception(string.Format("对象【{0}】属性【{1}】不存在", propertyExp.Type.Name, rule.Field));
                    }
                    propertyExp = Expression.Property(propertyExp, rule.Field);
                }
            }

            Type type = propertyExp.Type;

            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                type = type.GetGenericArguments()[0];
            }

            if (!DicTypeOperator.ContainsKey(type.Name) || !DicTypeOperator[type.Name].Contains(rule.Operator.ToLower()))
            {
                throw new Exception($"字段【{rule.Field}】不支持运算符【{rule.Operator}】");
            }

            Expression expression;

            // 检查输入数据的类型是否和字段类型兼容,例如字段类型是数字
            try
            {
                switch (rule.Operator.ToLower())
                {
                case "in":
                    expression = In(type, rule.Value, propertyExp);
                    break;

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

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

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

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

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

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

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

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

                case "greater_or_equal":
                    expression = GreaterThanOrEqual(type, rule.Value, propertyExp);
                    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 "mc":          // QT扩展运算符:多包含
                    expression = ContainsAny(type, rule.Value, propertyExp);
                    break;

                case "sdiff":       // QT扩展运算符:几天前,只应用于日期属性
                    expression = DaysBefore(type, rule.Value, propertyExp);
                    break;

                case "ediff":       // QT扩展运算符:几天后,只应用于日期属性
                    expression = DaysAfter(type, rule.Value, propertyExp);
                    break;

                default:
                    throw new Exception($"Unknown expression operator: {rule.Operator}");
                }
            }
            catch (NotSupportedException)
            {
                throw new Exception($"字段【{rule.Field}】输入值【{rule.Value}】不合法");
            }

            return(expression);
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the filtered collection after applying the provided filter rules.
        /// </summary>
        /// <typeparam name="T">The generic type.</typeparam>
        /// <param name="queryable">The queryable.</param>
        /// <param name="filterRule">The filter rule.</param>
        /// <param name="useIndexedProperty">Whether or not to use indexed property</param>
        /// <param name="indexedPropertyName">The indexable property to use</param>
        /// <returns>Filtered IQueryable</returns>
        public static IQueryable <T> BuildQuery <T>(this IQueryable <T> queryable, FilterRule filterRule, bool useIndexedProperty = false, string indexedPropertyName = null)
        {
            string parsedQuery;

            return(BuildQuery(queryable, filterRule, out parsedQuery, useIndexedProperty, indexedPropertyName));
        }