private MethodCallExpression Build(Expression outerSource, Expression innerSource, IReadOnlyList <IEdmNavigationProperty> joinPath, IEdmNavigationProperty navigationProperty, bool manyToMany)
        {
            Type outerType = OeExpressionHelper.GetCollectionItemType(outerSource.Type);
            Type innerType = OeExpressionHelper.GetCollectionItemType(innerSource.Type);

            LambdaExpression groupJoinOuterKeySelector = GetGroupJoinOuterKeySelector(outerType, navigationProperty, joinPath);
            LambdaExpression groupJoinInnerKeySelector = GetGroupJoinInnerKeySelector(innerType, navigationProperty);

            if (groupJoinOuterKeySelector.ReturnType != groupJoinInnerKeySelector.ReturnType)
            {
                Expression innerBody = CoerceExpression(groupJoinOuterKeySelector.Body, groupJoinInnerKeySelector.Body);
                if (innerBody.Type != groupJoinInnerKeySelector.ReturnType)
                {
                    groupJoinInnerKeySelector = Expression.Lambda(innerBody, groupJoinInnerKeySelector.Parameters[0]);
                }

                if (innerBody.Type != groupJoinOuterKeySelector.ReturnType)
                {
                    Expression outerBody = CoerceExpression(innerBody, groupJoinOuterKeySelector.Body);
                    groupJoinOuterKeySelector = Expression.Lambda(outerBody, groupJoinOuterKeySelector.Parameters[0]);
                }
            }

            LambdaExpression groupJoinResultSelect = GetGroupJoinResultSelector(outerType, innerType, manyToMany);

            MethodInfo           groupJoinMethodInfo = OeMethodInfoHelper.GetGroupJoinMethodInfo(outerType, innerType, groupJoinOuterKeySelector.ReturnType, groupJoinResultSelect.ReturnType);
            MethodCallExpression groupJoinCall       = Expression.Call(groupJoinMethodInfo, outerSource, innerSource, groupJoinOuterKeySelector, groupJoinInnerKeySelector, groupJoinResultSelect);

            LambdaExpression selectManySource         = GetSelectManyCollectionSelector(groupJoinResultSelect);
            LambdaExpression selectManyResultSelector = GetSelectManyResultSelector(groupJoinResultSelect);

            MethodInfo selectManyMethodInfo = OeMethodInfoHelper.GetSelectManyMethodInfo(groupJoinResultSelect.ReturnType, innerType, selectManyResultSelector.ReturnType);

            return(Expression.Call(selectManyMethodInfo, groupJoinCall, selectManySource, selectManyResultSelector));
        }
Example #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)));
        }
Example #3
0
        public static MethodCallExpression Build(Expression outer, Expression inner, ExpandedNavigationSelectItem item, ODataPath odataPath, OeExpressionBuilder expressionBuilder)
        {
            var segment = (NavigationPropertySegment)item.PathToNavigationProperty.LastSegment;

            Type       outerType      = OeExpressionHelper.GetCollectionItemType(outer.Type);
            var        outerParameter = Expression.Parameter(outerType, outerType.Name);
            Expression subquery       = CreateWhereExpression(outerParameter, inner, segment.NavigationProperty);

            subquery = expressionBuilder.ApplyOrderBy(subquery, item.OrderByOption);
            subquery = expressionBuilder.ApplySkip(subquery, item.SkipOption, odataPath);
            subquery = expressionBuilder.ApplyTake(subquery, item.TopOption, odataPath);

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

            return(Expression.Call(selectManyMethdoInfo, outer, Expression.Lambda(subquery, outerParameter)));
        }
Example #4
0
        private MethodCallExpression Build(Expression outerSource, Expression innerSource, IReadOnlyList <IEdmNavigationProperty> joinPath, IEdmNavigationProperty navigationProperty, bool manyToMany)
        {
            Type outerType = OeExpressionHelper.GetCollectionItemType(outerSource.Type);
            Type innerType = OeExpressionHelper.GetCollectionItemType(innerSource.Type);

            (LambdaExpression groupJoinOuterKeySelector, LambdaExpression groupJoinInnerKeySelector) = GetJoinKeySelector(outerType, innerType, joinPath, navigationProperty);
            LambdaExpression groupJoinResultSelect = GetGroupJoinResultSelector(outerType, innerType, manyToMany);

            MethodInfo           groupJoinMethodInfo = OeMethodInfoHelper.GetGroupJoinMethodInfo(outerType, innerType, groupJoinOuterKeySelector.ReturnType, groupJoinResultSelect.ReturnType);
            MethodCallExpression groupJoinCall       = Expression.Call(groupJoinMethodInfo, outerSource, innerSource, groupJoinOuterKeySelector, groupJoinInnerKeySelector, groupJoinResultSelect);

            LambdaExpression selectManySource         = GetSelectManyCollectionSelector(groupJoinResultSelect);
            LambdaExpression selectManyResultSelector = GetSelectManyResultSelector(groupJoinResultSelect);

            MethodInfo selectManyMethodInfo = OeMethodInfoHelper.GetSelectManyMethodInfo(groupJoinResultSelect.ReturnType, innerType, selectManyResultSelector.ReturnType);

            return(Expression.Call(selectManyMethodInfo, groupJoinCall, selectManySource, selectManyResultSelector));
        }