Ejemplo n.º 1
0
        public MethodCallExpression Build(IEdmModel edmModel, Expression outerSource, Expression innerSource,
                                          IReadOnlyList <IEdmNavigationProperty> joinPath, IEdmNavigationProperty navigationProperty)
        {
            if (navigationProperty.ContainsTarget)
            {
                ModelBuilder.ManyToManyJoinDescription joinDescription = edmModel.GetManyToManyJoinDescription(navigationProperty);
                IEdmEntitySet joinEntitySet = OeEdmClrHelper.GetEntitySet(edmModel, joinDescription.JoinNavigationProperty);
                Expression    joinSource    = OeEnumerableStub.CreateEnumerableStubExpression(joinDescription.JoinClassType, joinEntitySet);

                outerSource = Build(outerSource, joinSource, joinPath, joinDescription.JoinNavigationProperty, false);
                AddJoinPath(joinPath, joinDescription.JoinNavigationProperty);

                var fixedJoinPath = new IEdmNavigationProperty[joinPath.Count + 1];
                for (int i = 0; i < joinPath.Count; i++)
                {
                    fixedJoinPath[i] = joinPath[i];
                }
                fixedJoinPath[fixedJoinPath.Length - 1] = joinDescription.JoinNavigationProperty;

                outerSource = Build(outerSource, innerSource, fixedJoinPath, joinDescription.TargetNavigationProperty, true);
                _joinPaths.RemoveAt(_joinPaths.Count - 1);
            }
            else
            {
                outerSource = Build(outerSource, innerSource, joinPath, navigationProperty, false);
            }

            AddJoinPath(joinPath, navigationProperty);
            return((MethodCallExpression)outerSource);
        }
Ejemplo n.º 2
0
        public MethodCallExpression Build(Expression outer, Expression inner, ODataPath odataPath, OrderByClause orderBy, long?skip, long?top)
        {
            var segment = (NavigationPropertySegment)odataPath.LastSegment;
            IEdmNavigationProperty navigationProperty = segment.NavigationProperty;

            if (navigationProperty.ContainsTarget)
            {
                ModelBuilder.ManyToManyJoinDescription joinDescription = _edmModel.GetManyToManyJoinDescription(navigationProperty);
                IEdmEntitySet joinEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, joinDescription.JoinNavigationProperty);
                outer = OeEnumerableStub.CreateEnumerableStubExpression(joinDescription.JoinClassType, joinEntitySet);
                navigationProperty = joinDescription.TargetNavigationProperty;
            }

            Type outerType = OeExpressionHelper.GetCollectionItemType(outer.Type);
            ParameterExpression outerParameter = Expression.Parameter(outerType, outerType.Name);

            inner = new ReplaceParameterVisitor(outerParameter).Visit(inner); //replace $it
            Expression subquery = CreateWhereExpression(outerParameter, inner, navigationProperty);

            subquery = _expressionBuilder.ApplyOrderBy(subquery, orderBy);
            subquery = _expressionBuilder.ApplySkip(subquery, skip, odataPath);
            subquery = _expressionBuilder.ApplyTake(subquery, top, odataPath);

            Type       innerType            = OeExpressionHelper.GetCollectionItemType(inner.Type);
            MethodInfo selectManyMethdoInfo = OeMethodInfoHelper.GetSelectManyMethodInfo(outerType, innerType);

            return(Expression.Call(selectManyMethdoInfo, outer, Expression.Lambda(subquery, outerParameter)));
        }
Ejemplo n.º 3
0
        private Expression GetInnerSource(OeSelectItem navigationItem, ExpandedNavigationSelectItem item)
        {
            Type         clrEntityType         = _visitor.EdmModel.GetClrType(navigationItem.EdmProperty.DeclaringType);
            PropertyInfo navigationClrProperty = clrEntityType.GetPropertyIgnoreCase(navigationItem.EdmProperty);

            Type itemType = OeExpressionHelper.GetCollectionItemType(navigationClrProperty.PropertyType);

            if (itemType == null)
            {
                itemType = navigationClrProperty.PropertyType;
            }

            var visitor           = new OeQueryNodeVisitor(_visitor, Expression.Parameter(itemType));
            var expressionBuilder = new OeExpressionBuilder(_joinBuilder, visitor);

            var navigationEdmProperty = (IEdmNavigationProperty)navigationItem.EdmProperty;

            if (navigationEdmProperty.ContainsTarget)
            {
                ModelBuilder.ManyToManyJoinDescription joinDescription = _visitor.EdmModel.GetManyToManyJoinDescription(navigationEdmProperty);
                navigationEdmProperty = joinDescription.TargetNavigationProperty;
            }
            IEdmEntitySet innerEntitySet = OeEdmClrHelper.GetEntitySet(_visitor.EdmModel, navigationEdmProperty);
            Expression    innerSource    = OeEnumerableStub.CreateEnumerableStubExpression(itemType, innerEntitySet);

            innerSource = expressionBuilder.ApplyFilter(innerSource, item.FilterOption);
            if (item.SkipOption != null || item.TopOption != null)
            {
                Expression source = OeEnumerableStub.CreateEnumerableStubExpression(navigationClrProperty.DeclaringType, (IEdmEntitySet)_navigationItem.EntitySet);
                innerSource = OeCrossApplyBuilder.Build(source, innerSource, item, navigationItem.Path, expressionBuilder);
            }

            return(innerSource);
        }
Ejemplo n.º 4
0
        private Expression GetInnerSource(OeNavigationSelectItem navigationItem)
        {
            if (navigationItem.Parent == null)
            {
                throw new InvalidOperationException("Inner source cannot exist for root item");
            }

            Type         clrEntityType         = _edmModel.GetClrType(navigationItem.EdmProperty.DeclaringType);
            PropertyInfo navigationClrProperty = clrEntityType.GetPropertyIgnoreCase(navigationItem.EdmProperty);

            Type itemType          = OeExpressionHelper.GetCollectionItemTypeOrNull(navigationClrProperty.PropertyType) ?? navigationClrProperty.PropertyType;
            var  visitor           = new OeQueryNodeVisitor(_joinBuilder.Visitor, Expression.Parameter(itemType));
            var  expressionBuilder = new OeExpressionBuilder(_joinBuilder, visitor);

            IEdmNavigationProperty navigationProperty = navigationItem.EdmProperty;

            if (navigationItem.EdmProperty.ContainsTarget)
            {
                ModelBuilder.ManyToManyJoinDescription joinDescription = _edmModel.GetManyToManyJoinDescription(navigationProperty);
                navigationProperty = joinDescription.TargetNavigationProperty;
            }
            IEdmEntitySet innerEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, navigationProperty);
            Expression    innerSource    = OeEnumerableStub.CreateEnumerableStubExpression(itemType, innerEntitySet);

            ExpandedNavigationSelectItem item = navigationItem.NavigationSelectItem;

            innerSource = expressionBuilder.ApplyFilter(innerSource, item.FilterOption);

            long?top = GetTop(navigationItem, item.TopOption);

            if (top == null && item.SkipOption == null)
            {
                return(innerSource);
            }

            OrderByClause orderByClause = item.OrderByOption;

            if (navigationItem.PageSize > 0)
            {
                orderByClause = OeSkipTokenParser.GetUniqueOrderBy(navigationItem.EntitySet, item.OrderByOption, null);
            }

            var        entitySet = (IEdmEntitySet)navigationItem.Parent.EntitySet;
            Expression source    = OeEnumerableStub.CreateEnumerableStubExpression(navigationClrProperty.DeclaringType, entitySet);

            var crossApplyBuilder = new OeCrossApplyBuilder(_edmModel, expressionBuilder);

            return(crossApplyBuilder.Build(source, innerSource, navigationItem.Path, orderByClause, item.SkipOption, top));
        }