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.GetTypeInfo().GetProperty(nameof(IGrouping <Object, Object> .Key));
                MemberExpression key         = Expression.Property(sourceParameter, keyProperty);
                expressions.Add(key);

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

            var visitor = CreateVisitor(lambdaParameter);

            foreach (AggregateExpression aggExpression in transformation.Expressions)
            {
                Expression           e                 = visitor.TranslateNode(aggExpression.Expression);
                LambdaExpression     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));
        }
示例#2
0
        public Expression ApplyNavigation(Expression source, IEnumerable <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
                {
                    parameter  = Parameter;
                    e          = source;
                    selectType = sourceItemType;
                }
                else
                {
                    parameter = Expression.Parameter(sourceItemType);
                    PropertyInfo navigationClrProperty = sourceItemType.GetTypeInfo().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);
                }

                _entityType    = selectType;
                sourceItemType = selectType;
            }

            _visitor = new OeQueryNodeVisitor(_model, Expression.Parameter(_entityType), _visitor.Constans);
            return(source);
        }
        private MethodCallExpression CreateSelectExpression(Expression source, ParameterExpression parameter)
        {
            NewExpression    newExpression    = CreateTupleExpression();
            LambdaExpression lambda           = Expression.Lambda(newExpression, parameter);
            MethodInfo       selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(parameter.Type, newExpression.Type);

            return(Expression.Call(selectMethodInfo, source, lambda));
        }
示例#4
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.GetPropertyIgnoreCase(parseNavigationSegment.NavigationSegment.NavigationProperty);
                    e = Expression.MakeMemberAccess(parameter, navigationClrProperty);

                    MethodInfo selectMethodInfo;
                    selectType = OeExpressionHelper.GetCollectionItemTypeOrNull(e.Type) ?? e.Type;
                    if (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);
        }
示例#5
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));
        }
示例#6
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));
        }
        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));
        }
示例#8
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));
        }