コード例 #1
0
        public SpecificationBase <T> Create <T>(FilterOption filter)
        {
            var expression = this.CreateExpression <T>(filter);


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

            var spec = new SpecificationBase <T>(expression);

            return(spec);
        }
コード例 #2
0
        private Expression <Func <T, bool> > CreateMemberExpressionSimple <T>(FilterOption filter)
        {
            var left = ExpressionExtensions.MakePropertyExpression <T>(filter.Member);
            //TODO: change type
            var right = this.GetExpressionValue(filter, left.Item3);

            //FilterOperator Switch
            var assign = this.GetAssignExpression(left.Item3, filter.Operator, left.Item1, right);

            if (assign == null)
            {
                return(null);
            }
            return(Expression.Lambda <Func <T, bool> >(assign, left.Item2));
        }
コード例 #3
0
        private Expression <Func <T, bool> > CreateExpression <T>(FilterOption filter)
        {
            //TODO: use c# 7 named value tuples or create an object with more explicit names
            Expression <Func <T, bool> > expression;
            var index = filter.Member.IndexOfAny(this.CompositeCharOperators);

            if (index > -1)
            {
                expression = this.CreateMemberExpressionComposite <T>(filter, index);
            }

            else
            {
                expression = this.CreateMemberExpressionSimple <T>(filter);
            }

            return(expression);
        }
コード例 #4
0
        private ConstantExpression GetExpressionValue(FilterOption filter, Type properType)
        {
            // Filter by month and year
            if (properType == typeof(DateTime) &&
                (int.TryParse(filter.Value, out int c) ||
                 Regex.Match(filter.Value.ToString(), GenericConstants._GENERIC_MONTH_YEAR_EXPRESSION, RegexOptions.IgnoreCase).Success) ||
                Regex.Match(filter.Value.ToString(), GenericConstants._GENERIC_YEAR_MONTH_EXPRESSION, RegexOptions.IgnoreCase).Success)
            {
                return(Expression.Constant(filter.Value.ConvertTo(typeof(string)), typeof(string)));
            }

            switch (filter.Operator)
            {
            case FilterOperator.IsLessThan:
            case FilterOperator.IsLessThanOrEqualTo:
            case FilterOperator.IsEqualTo:
            case FilterOperator.IsNotEqualTo:
            case FilterOperator.IsGreaterThan:
            case FilterOperator.IsGreaterThanOrEqualTo:
            case FilterOperator.StartsWith:
            case FilterOperator.EndsWith:
            case FilterOperator.Contains:
            case FilterOperator.DoesNotContain:
                var effectiveValue = filter.Value.ConvertTo(properType);
                return(Expression.Constant(effectiveValue, properType));

            case FilterOperator.IsContainedIn:
            case FilterOperator.IsNotContainedIn:
                var array             = filter.Value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                var arrayValues       = array.Select(x => x.ConvertTo(properType));
                var castMethod        = EnumerableExtensions.CastMethod;
                var genericCastMethod = castMethod.MakeGenericMethod(properType);
                var obj = genericCastMethod.Invoke(null, new object[] { arrayValues });
                return(Expression.Constant(obj));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #5
0
        private Expression <Func <T, bool> > CreateMemberExpressionComposite <T>(FilterOption filter, int index)
        {
            var collectionPath    = filter.Member.Substring(0, index);
            var separator         = filter.Member[index];
            var childPropertyPath = filter.Member.Substring(index + 1, (filter.Member.Length - (index + 1)));
            var childFilter       = new FilterOption
            {
                Member   = childPropertyPath,
                Operator = filter.Operator,
                Value    = filter.Value
            };

            var collectionInfo              = ExpressionExtensions.MakePropertyExpression <T>(collectionPath);
            var collectionPropertyTye       = collectionInfo.Item3;
            var collectionChildPropertyType = collectionPropertyTye.GenericTypeArguments[0];

            var createMethod    = CreateExpressionMethodInfo.MakeGenericMethod(collectionChildPropertyType);
            var childExpression = createMethod.Invoke(this, new object[] { childFilter }) as Expression;

            if (childExpression == null)
            {
                return(null);
            }

            var method         = this.CompositeCharMethods[separator];
            var concreteMethod = method.MakeGenericMethod(collectionChildPropertyType);

            IEnumerable <Expression> parameters = new[]
            {
                collectionInfo.Item1, childExpression
            };
            var exp        = Expression.Call(null, concreteMethod, parameters);
            var expression = Expression.Lambda <Func <T, bool> >(exp, collectionInfo.Item2);

            return(expression);
        }