Exemplo n.º 1
0
        public Expression ApplyNavigation(Expression source, IReadOnlyList <OeParseNavigationSegment> parseNavigationSegments)
        {
            if (parseNavigationSegments == null)
            {
                return(source);
            }

            Type sourceItemType = OeExpressionHelper.GetCollectionItemType(source.Type);

            foreach (OeParseNavigationSegment parseNavigationSegment in parseNavigationSegments)
            {
                Type selectType;
                ParameterExpression parameter;
                Expression          e;
                if (parseNavigationSegment.NavigationSegment == null) //EntitySetSegment, KeySegment
                {
                    parameter  = Visitor.Parameter;
                    e          = source;
                    selectType = sourceItemType;
                }
                else
                {
                    parameter = Expression.Parameter(sourceItemType);
                    PropertyInfo navigationClrProperty = sourceItemType.GetProperty(parseNavigationSegment.NavigationSegment.NavigationProperty.Name);
                    e = Expression.MakeMemberAccess(parameter, navigationClrProperty);

                    MethodInfo selectMethodInfo;
                    selectType = OeExpressionHelper.GetCollectionItemType(e.Type);
                    if (selectType == null)
                    {
                        selectType       = e.Type;
                        selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceItemType, selectType);
                    }
                    else
                    {
                        selectMethodInfo = OeMethodInfoHelper.GetSelectManyMethodInfo(sourceItemType, selectType);
                    }

                    LambdaExpression lambda = Expression.Lambda(e, parameter);
                    source = Expression.Call(selectMethodInfo, source, lambda);
                }

                if (parseNavigationSegment.Filter != null)
                {
                    var visitor = new OeQueryNodeVisitor(Visitor, Expression.Parameter(selectType));
                    e = visitor.TranslateNode(parseNavigationSegment.Filter.Expression);
                    LambdaExpression lambda = Expression.Lambda(e, visitor.Parameter);

                    MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(selectType);
                    source = Expression.Call(whereMethodInfo, source, lambda);
                }

                sourceItemType = selectType;
            }

            Visitor.ChangeParameterType(Expression.Parameter(sourceItemType));
            return(source);
        }
        private static MethodCallExpression AggCallExpression(AggregationMethod aggMethod, ParameterExpression sourceParameter, LambdaExpression lambda)
        {
            String methodName;

            switch (aggMethod)
            {
            case AggregationMethod.Average:
                methodName = nameof(Enumerable.Average);
                break;

            case AggregationMethod.CountDistinct:
                return(CountDistinctExpression(sourceParameter, lambda));

            case AggregationMethod.Max:
                methodName = nameof(Enumerable.Max);
                break;

            case AggregationMethod.Min:
                methodName = nameof(Enumerable.Min);
                break;

            case AggregationMethod.Sum:
                methodName = nameof(Enumerable.Sum);
                break;

            default:
                throw new NotSupportedException();
            }

            MethodInfo closeMethod;
            MethodInfo openMethod = OeMethodInfoHelper.GetAggMethodInfo(methodName, lambda.ReturnType);

            if (openMethod == null)
            {
                Func <IEnumerable <Object>, Func <Object, Object>, Object> aggFunc;
                switch (aggMethod)
                {
                case AggregationMethod.Max:
                    aggFunc = Enumerable.Max <Object, Object>;
                    break;

                case AggregationMethod.Min:
                    aggFunc = Enumerable.Min <Object, Object>;
                    break;

                default:
                    throw new InvalidOperationException($"Enumerable.{methodName} not found");;
                }
                openMethod  = aggFunc.GetMethodInfo().GetGenericMethodDefinition();
                closeMethod = openMethod.MakeGenericMethod(lambda.Parameters[0].Type, lambda.ReturnType);
            }
            else
            {
                closeMethod = openMethod.MakeGenericMethod(lambda.Parameters[0].Type);
            }

            return(Expression.Call(closeMethod, sourceParameter, lambda));
        }
Exemplo n.º 3
0
        private MethodCallExpression ApplyGroupBy(Expression source, GroupByTransformationNode transformation)
        {
            Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type);
            ParameterExpression sourceParameter = Expression.Parameter(sourceType);
            var visitor = CreateVisitor(sourceParameter);

            var expressions = new List <Expression>();

            foreach (GroupByPropertyNode node in transformation.GroupingProperties)
            {
                if (node.ChildTransformations != null && node.ChildTransformations.Count > 0)
                {
                    if (node.ChildTransformations.Count > 1)
                    {
                        throw new NotSupportedException();
                    }

                    GroupByPropertyNode childNode = node.ChildTransformations[0];
                    String propertyName           = node.Name + "_" + childNode.Name;

                    Expression e = visitor.TranslateNode(childNode.Expression);
                    expressions.Add(e);

                    _aggProperties.Add(CreateEdmProperty(_visitor.EdmModel, e.Type, propertyName, true));
                }
                else
                {
                    Expression e = visitor.TranslateNode(node.Expression);
                    expressions.Add(e);

                    _aggProperties.Add(CreateEdmProperty(_visitor.EdmModel, e.Type, node.Name, true));
                }
            }

            NewExpression    newExpression = OeExpressionHelper.CreateTupleExpression(expressions);
            LambdaExpression lambda        = Expression.Lambda(newExpression, sourceParameter);

            MethodInfo           groupByMethodInfo = OeMethodInfoHelper.GetGroupByMethodInfo(sourceType, newExpression.Type);
            MethodCallExpression groupByCall       = Expression.Call(groupByMethodInfo, source, lambda);

            var aggTransformation = (AggregateTransformationNode)transformation.ChildTransformations;

            if (aggTransformation == null)
            {
                expressions.Clear();
                sourceType      = OeExpressionHelper.GetCollectionItemType(groupByCall.Type);
                sourceParameter = Expression.Parameter(sourceType);
                expressions.Add(Expression.Property(sourceParameter, nameof(IGrouping <Object, Object> .Key)));
                newExpression = OeExpressionHelper.CreateTupleExpression(expressions);

                MethodInfo selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceType, newExpression.Type);
                lambda = Expression.Lambda(newExpression, sourceParameter);
                return(Expression.Call(selectMethodInfo, groupByCall, lambda));
            }

            return(ApplyAggregate(groupByCall, aggTransformation));
        }
Exemplo n.º 4
0
        public override Expression Translate(ExpandedNavigationSelectItem item)
        {
            var        segment            = (NavigationPropertySegment)item.PathToNavigationProperty.LastSegment;
            Expression expression         = Translate(segment);
            Type       navigationItemType = expression.Type;

            Type itemType = OeExpressionHelper.GetCollectionItemType(navigationItemType);

            if (itemType != null)
            {
                var expressionBuilder = new OeExpressionBuilder(_model, itemType);
                expression = expressionBuilder.ApplyFilter(expression, item.FilterOption);
                expression = expressionBuilder.ApplyOrderBy(expression, item.OrderByOption);

                var path = new ODataPath(_path.Union(item.PathToNavigationProperty));
                expression = expressionBuilder.ApplySkip(expression, item.SkipOption, path);
                expression = expressionBuilder.ApplyTake(expression, item.TopOption, path);

                foreach (KeyValuePair <ConstantExpression, ConstantNode> constant in expressionBuilder.Constants)
                {
                    _visitor.AddConstant(constant.Key, constant.Value);
                }
            }

            Expression countExpression = null;

            if (item.CountOption.GetValueOrDefault())
            {
                MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(itemType);
                countExpression = Expression.Call(countMethodInfo, expression);
            }

            if (item.SelectAndExpand.SelectedItems.Any())
            {
                var        path             = new ODataPath(_path.Union(item.PathToNavigationProperty));
                var        selectTranslator = new OeSelectTranslator(_visitor, path);
                Expression nestedExpression = selectTranslator.CreateExpression(expression, item.SelectAndExpand, OeMetadataLevel.Minimal);

                Type nestedType = OeExpressionHelper.GetCollectionItemType(nestedExpression.Type);
                if (nestedType == null)
                {
                    var visitor = new ParameterVisitor(selectTranslator._parameter, expression);
                    nestedExpression = visitor.Visit(nestedExpression);
                    nestedType       = nestedExpression.Type;
                }

                _selectItemInfo.EntryFactory = selectTranslator.CreateNestedEntryFactory(nestedType, _selectItemInfo.EntitySet, _selectItemInfo.ResourceInfo);
                expression = nestedExpression;
            }

            if (countExpression != null)
            {
                return(CreateNavigationLinkInfo(navigationItemType, expression, countExpression));
            }

            return(expression);
        }
Exemplo n.º 5
0
        public Expression CreateCountExpression(IQueryable query, Expression expression)
        {
            Type       filterType       = EntryFactory == null ? query.ElementType : EdmModel.GetClrType(EntryFactory.EntityType);
            Expression filterExpression = ODataUri.Filter == null ? query.Expression : FilterVisitor.Translate(query, expression, filterType);

            Type       sourceType      = OeExpressionHelper.GetCollectionItemType(filterExpression.Type);
            MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType);

            return(Expression.Call(countMethodInfo, filterExpression));
        }
        public Expression Build(Expression source, IReadOnlyList <OeSkipTokenNameValue> skipTokenNameValues, OrderByClause uniqueOrderBy)
        {
            OrderProperty[] orderProperties = CreateOrderProperies(source, _visitor, skipTokenNameValues, uniqueOrderBy);
            Expression      filter          = CreateFilterExpression(_visitor, _isDatabaseNullHighestValue, orderProperties);

            LambdaExpression lambda          = Expression.Lambda(filter, _visitor.Parameter);
            MethodInfo       whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(_visitor.Parameter.Type);

            return(Expression.Call(whereMethodInfo, source, lambda));
        }
        public Expression Build(Expression source, String skipToken)
        {
            OrderProperty[] orderProperties = CreateOrderProperies(_skipTokenParser, skipToken);
            Expression      filter          = CreateFilterExpression(source, _visitor, _skipTokenParser.IsDatabaseNullHighestValue, orderProperties);

            LambdaExpression lambda          = Expression.Lambda(filter, _visitor.Parameter);
            MethodInfo       whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(_visitor.Parameter.Type);

            return(Expression.Call(whereMethodInfo, source, lambda));
        }
Exemplo n.º 8
0
        public Expression ApplyCount(Expression source, bool?queryCount)
        {
            if (!queryCount.GetValueOrDefault())
            {
                return(source);
            }

            MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(ParameterType);

            return(Expression.Call(countMethodInfo, source));
        }
        public Expression ApplySkip(Expression source, long?skip, ODataPath path)
        {
            if (skip == null)
            {
                return(source);
            }

            ConstantExpression skipConstant   = Visitor.AddSkipConstant((int)skip.Value, path);
            MethodInfo         skipMethodInfo = OeMethodInfoHelper.GetSkipMethodInfo(ParameterType);

            return(Expression.Call(skipMethodInfo, source, skipConstant));
        }
Exemplo n.º 10
0
        private static MethodCallExpression CountDistinctExpression(ParameterExpression sourceParameter, LambdaExpression lambda)
        {
            MethodInfo           selectMetodInfo = OeMethodInfoHelper.GetSelectMethodInfo(lambda.Parameters[0].Type, lambda.ReturnType);
            MethodCallExpression selectCall      = Expression.Call(selectMetodInfo, sourceParameter, lambda);

            MethodInfo           distinctMethodInfo = OeMethodInfoHelper.GetDistinctMethodInfo(lambda.ReturnType);
            MethodCallExpression distinctCall       = Expression.Call(distinctMethodInfo, selectCall);

            MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(lambda.ReturnType);

            return(Expression.Call(countMethodInfo, distinctCall));
        }
        public Expression ApplyTake(Expression source, long?top, ODataPath path)
        {
            if (top == null)
            {
                return(source);
            }

            ConstantExpression topConstant    = Visitor.AddTopConstant((int)top.Value, path);
            MethodInfo         takeMethodInfo = OeMethodInfoHelper.GetTakeMethodInfo(ParameterType);

            return(Expression.Call(takeMethodInfo, source, topConstant));
        }
Exemplo n.º 12
0
        private Expression CreateExpression(Expression source, SelectExpandClause selectClause, OeMetadataLevel metadatLevel)
        {
            Type itemType = OeExpressionHelper.GetCollectionItemType(source.Type);

            if (itemType == null)
            {
                _parameter = Expression.Parameter(source.Type);
            }
            else
            {
                _parameter = Expression.Parameter(itemType);
            }

            var expressions = new List <Expression>();

            foreach (SelectItem selectItem in selectClause.SelectedItems)
            {
                Expression expression = selectItem.TranslateWith(this);
                if (SelectItemInfoExists(_selectItemInfo.EdmProperty))
                {
                    continue;
                }

                expressions.Add(expression);
                _selectItemInfos.Add(_selectItemInfo);
            }

            if (_pathSelect)
            {
                if (metadatLevel == OeMetadataLevel.Full)
                {
                    AddKey(itemType, expressions);
                }
            }
            else
            {
                expressions.Insert(0, _parameter);
            }

            NewExpression newExpression = OeExpressionHelper.CreateTupleExpression(expressions);

            if (itemType == null)
            {
                return(newExpression);
            }

            LambdaExpression lambda           = Expression.Lambda(newExpression, _parameter);
            MethodInfo       selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(_parameter.Type, newExpression.Type);

            return(Expression.Call(selectMethodInfo, source, lambda));
        }
Exemplo n.º 13
0
        public Expression ApplyFilter(Expression source, FilterClause filterClause)
        {
            if (filterClause == null)
            {
                return(source);
            }

            Expression       e      = Visitor.TranslateNode(filterClause.Expression);
            LambdaExpression lambda = Expression.Lambda(e, Visitor.Parameter);

            MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(ParameterType);

            return(Expression.Call(whereMethodInfo, source, lambda));
        }
Exemplo n.º 14
0
        private Expression ApplyThenBy(Expression source, OrderByClause thenByClause)
        {
            if (thenByClause == null)
            {
                return(source);
            }

            Expression       e      = _visitor.TranslateNode(thenByClause.Expression);
            LambdaExpression lambda = Expression.Lambda(e, Parameter);

            MethodInfo thenByMethodInfo = thenByClause.Direction == OrderByDirection.Ascending ?
                                          OeMethodInfoHelper.GetThenByMethodInfo(ParameterType, e.Type) :
                                          OeMethodInfoHelper.GetThenByDescendingMethodInfo(ParameterType, e.Type);
            MethodCallExpression thenByCall = Expression.Call(thenByMethodInfo, source, lambda);

            return(ApplyThenBy(thenByCall, thenByClause.ThenBy));
        }
            private MethodCallExpression GetJoin(Expression innerSource, IEdmNavigationProperty navigationProperty)
            {
                Type outerType = OeExpressionHelper.GetCollectionItemType(_outerSource.Type);
                Type innerType = OeExpressionHelper.GetCollectionItemType(innerSource.Type);

                var joinBuilder = new OeJoinBuilder(new OeQueryNodeVisitor(_outerParameterExpression));

                (LambdaExpression outerKeySelector, LambdaExpression innerKeySelector) =
                    joinBuilder.GetJoinKeySelector(outerType, innerType, Array.Empty <IEdmNavigationProperty>(), navigationProperty);

                var        replaceParameterVisitor = new ReplaceParameterVisitor(_outerParameterExpression, outerKeySelector.Parameters[0]);
                Expression outerKeyExpression      = replaceParameterVisitor.Visit(outerKeySelector.Body);
                IReadOnlyList <MemberExpression> outerKeyProperties;
                IReadOnlyList <MemberExpression> innerKeyProperties;

                if (OeExpressionHelper.IsTupleType(outerKeySelector.ReturnType))
                {
                    outerKeyProperties = OeExpressionHelper.GetPropertyExpressions(outerKeyExpression);
                    innerKeyProperties = OeExpressionHelper.GetPropertyExpressions(innerKeySelector.Body);
                }
                else
                {
                    outerKeyProperties = new MemberExpression[] { (MemberExpression)outerKeyExpression };
                    innerKeyProperties = new MemberExpression[] { (MemberExpression)innerKeySelector.Body };
                }

                BinaryExpression?joinExpression = null;

                for (int i = 0; i < outerKeyProperties.Count; i++)
                {
                    if (joinExpression == null)
                    {
                        joinExpression = Expression.MakeBinary(ExpressionType.Equal, outerKeyProperties[i], innerKeyProperties[i]);
                    }
                    else
                    {
                        BinaryExpression equal = Expression.MakeBinary(ExpressionType.Equal, outerKeyProperties[i], innerKeyProperties[i]);
                        joinExpression = Expression.MakeBinary(ExpressionType.AndAlso, joinExpression, equal);
                    }
                }

                MethodInfo       whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(innerType);
                LambdaExpression joinLambda      = Expression.Lambda(joinExpression !, innerKeySelector.Parameters);

                return(Expression.Call(whereMethodInfo, innerSource, joinLambda));
            }
Exemplo n.º 16
0
        public static MethodCallExpression CreateCountExpression(Expression expression)
        {
            var filterVisitor = new FilterVisitor();

            filterVisitor.Visit(expression);

            Expression whereExpression = filterVisitor.WhereExpression;

            if (whereExpression == null)
            {
                whereExpression = filterVisitor.Source;
            }

            Type       sourceType      = OeExpressionHelper.GetCollectionItemType(whereExpression.Type);
            MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType);

            return(Expression.Call(countMethodInfo, whereExpression));
        }
Exemplo n.º 17
0
        private MethodCallExpression ApplyFilter(Expression source, FilterTransformationNode transformation)
        {
            Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type);
            ParameterExpression sourceParameter = Expression.Parameter(sourceType);

            var visitor = CreateVisitor(sourceParameter);

            if (_aggProperties.Count > 0)
            {
                visitor.TuplePropertyByAliasName = GetTuplePropertyByAliasName;
            }
            Expression e = visitor.TranslateNode(transformation.FilterClause.Expression);

            MethodInfo       whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(sourceParameter.Type);
            LambdaExpression lambda          = Expression.Lambda(e, sourceParameter);

            return(Expression.Call(whereMethodInfo, source, lambda));
        }
Exemplo n.º 18
0
        private MethodCallExpression ApplyAggregate(Expression source, AggregateTransformationNode transformation)
        {
            Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type);
            ParameterExpression sourceParameter = Expression.Parameter(sourceType);
            ParameterExpression lambdaParameter = sourceParameter;

            var expressions = new List <Expression>();

            if (sourceType.GetGenericTypeDefinition() == typeof(IGrouping <,>))
            {
                PropertyInfo     keyProperty = sourceType.GetProperty(nameof(IGrouping <Object, Object> .Key));
                MemberExpression key         = Expression.Property(sourceParameter, keyProperty);
                expressions.Add(key);

                lambdaParameter = Expression.Parameter(sourceType.GetGenericArguments()[1]);
            }

            var visitor = CreateVisitor(lambdaParameter);

            foreach (AggregateExpression aggExpression in transformation.Expressions)
            {
                LambdaExpression aggLambda = null;
                if (aggExpression.Expression.Kind != QueryNodeKind.Count)
                {
                    Expression e = visitor.TranslateNode(aggExpression.Expression);
                    aggLambda = Expression.Lambda(e, lambdaParameter);
                }

                MethodCallExpression aggCallExpression = AggCallExpression(aggExpression.Method, sourceParameter, aggLambda);
                expressions.Add(aggCallExpression);

                _aggProperties.Add(CreateEdmProperty(_visitor.EdmModel, aggCallExpression.Type, aggExpression.Alias, false));
            }

            NewExpression    newExpression    = OeExpressionHelper.CreateTupleExpression(expressions);
            MethodInfo       selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceType, newExpression.Type);
            LambdaExpression lambda           = Expression.Lambda(newExpression, sourceParameter);

            return(Expression.Call(selectMethodInfo, source, lambda));
        }
Exemplo n.º 19
0
        private MethodCallExpression ApplyCompute(Expression source, ComputeTransformationNode transformation)
        {
            var expressions = new List <Expression>();

            Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type);
            ParameterExpression sourceParameter = Expression.Parameter(sourceType);

            if (_aggProperties.Count > 0)
            {
                var callExpression = (MethodCallExpression)source;
                source = callExpression.Arguments[0];
                var aggLambda = (LambdaExpression)callExpression.Arguments[1];
                expressions.AddRange(((NewExpression)aggLambda.Body).Arguments);

                sourceType      = OeExpressionHelper.GetCollectionItemType(source.Type);
                sourceParameter = aggLambda.Parameters[0];
            }

            OeQueryNodeVisitor visitor = CreateVisitor(sourceParameter);

            if (_aggProperties.Count > 0)
            {
                visitor.TuplePropertyByAliasName = new ComputeAliasNameResolver(_aggProperties, expressions).GetTuplePropertyByAliasName;
            }

            foreach (ComputeExpression computeExpression in transformation.Expressions)
            {
                Expression expression = visitor.TranslateNode(computeExpression.Expression);
                expressions.Add(expression);

                _aggProperties.Add(CreateEdmProperty(visitor.EdmModel, expression.Type, computeExpression.Alias, false));
            }

            NewExpression    newExpression    = OeExpressionHelper.CreateTupleExpression(expressions);
            MethodInfo       selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceParameter.Type, newExpression.Type);
            LambdaExpression lambda           = Expression.Lambda(newExpression, sourceParameter);

            return(Expression.Call(selectMethodInfo, source, lambda));
        }
Exemplo n.º 20
0
        public MethodCallExpression CreateCountExpression(Expression source)
        {
            if (EntryFactory == null)
            {
                return(null);
            }

            Type sourceType    = EdmModel.GetClrType(EntryFactory.EntitySet);
            var  filterVisitor = new FilterVisitor(sourceType);

            filterVisitor.Visit(source);

            Expression whereExpression = filterVisitor.WhereExpression;

            if (whereExpression == null)
            {
                whereExpression = filterVisitor.Source;
            }

            MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType);

            return(Expression.Call(countMethodInfo, whereExpression));
        }
Exemplo n.º 21
0
        public MethodCallExpression CreateCountExpression(Expression source)
        {
            if (EntryFactory == null)
            {
                throw new InvalidOperationException("Cannot get count expression for scalar result expression");
            }

            Type sourceType    = EdmModel.GetClrType(EntryFactory.EntitySet);
            var  filterVisitor = new FilterVisitor(sourceType);

            filterVisitor.Visit(source);

            Expression?whereExpression = filterVisitor.WhereExpression;

            if (whereExpression == null)
            {
                whereExpression = filterVisitor.Source;
            }

            MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType);

            return(Expression.Call(countMethodInfo, whereExpression));
        }
 private static MethodInfo GetThenByMethodInfo(OrderByDirection direction, Type sourceType, Type keyType)
 {
     return(direction == OrderByDirection.Ascending ?
            OeMethodInfoHelper.GetThenByMethodInfo(sourceType, keyType) :
            OeMethodInfoHelper.GetThenByDescendingMethodInfo(sourceType, keyType));
 }