示例#1
0
        protected override Expression VisitExtension(Expression extensionExpression)
        {
            if (extensionExpression is NavigationBindingExpression navigationBindingExpression)
            {
                var result = navigationBindingExpression.RootParameter.BuildPropertyAccess(navigationBindingExpression.NavigationTreeNode.ToMapping);

                return(result);
            }

            if (extensionExpression is NavigationExpansionRootExpression navigationExpansionRootExpression)
            {
                return(Visit(navigationExpansionRootExpression.Unwrap()));
            }

            if (extensionExpression is NavigationExpansionExpression navigationExpansionExpression)
            {
                var includeResult = ApplyIncludes(navigationExpansionExpression);
                var state         = includeResult.state;
                var result        = Visit(includeResult.operand);

                if (!state.ApplyPendingSelector &&
                    state.PendingOrderings.Count == 0 &&
                    state.PendingTags.Count == 0 &&
                    state.PendingCardinalityReducingOperator == null &&
                    state.MaterializeCollectionNavigation == null)
                {
                    return(result);
                }

                var parameter = Expression.Parameter(result.Type.GetSequenceType());

                foreach (var pendingOrdering in state.PendingOrderings)
                {
                    var remappedKeySelectorBody = new ExpressionReplacingVisitor(pendingOrdering.keySelector.Parameters[0], state.CurrentParameter).Visit(pendingOrdering.keySelector.Body);
                    var newSelectorBody         = new NavigationPropertyUnbindingVisitor(state.CurrentParameter).Visit(remappedKeySelectorBody);
                    var newSelector             = Expression.Lambda(newSelectorBody, state.CurrentParameter);
                    var orderingMethod          = pendingOrdering.method.MakeGenericMethod(state.CurrentParameter.Type, newSelectorBody.Type);
                    result = Expression.Call(orderingMethod, result, newSelector);
                }

                if (state.ApplyPendingSelector)
                {
                    var pendingSelector         = (LambdaExpression) new NavigationPropertyUnbindingVisitor(state.CurrentParameter).Visit(state.PendingSelector);
                    var pendingSelectorBodyType = pendingSelector.Type.GetGenericArguments()[1];

                    var pendingSelectMathod = result.Type.IsGenericType && (result.Type.GetGenericTypeDefinition() == typeof(IEnumerable <>) || result.Type.GetGenericTypeDefinition() == typeof(IOrderedEnumerable <>))
                        ? LinqMethodHelpers.EnumerableSelectMethodInfo.MakeGenericMethod(parameter.Type, pendingSelectorBodyType)
                        : LinqMethodHelpers.QueryableSelectMethodInfo.MakeGenericMethod(parameter.Type, pendingSelectorBodyType);

                    result    = Expression.Call(pendingSelectMathod, result, pendingSelector);
                    parameter = Expression.Parameter(result.Type.GetSequenceType());
                }

                if (state.PendingTags.Count > 0)
                {
                    var withTagMethodInfo = EntityFrameworkQueryableExtensions.TagWithMethodInfo.MakeGenericMethod(parameter.Type);
                    foreach (var pendingTag in state.PendingTags)
                    {
                        result = Expression.Call(withTagMethodInfo, result, Expression.Constant(pendingTag));
                    }
                }

                if (state.PendingCardinalityReducingOperator != null)
                {
                    var terminatingOperatorMethodInfo = state.PendingCardinalityReducingOperator.MakeGenericMethod(parameter.Type);

                    result = Expression.Call(terminatingOperatorMethodInfo, result);
                }

                if (state.MaterializeCollectionNavigation != null)
                {
                    var entityType = state.MaterializeCollectionNavigation.ClrType.IsGenericType
                        ? state.MaterializeCollectionNavigation.ClrType.GetGenericArguments()[0]
                        : state.MaterializeCollectionNavigation.GetTargetType().ClrType;

                    result = Expression.Call(
                        NavigationExpansionHelpers.MaterializeCollectionNavigationMethodInfo.MakeGenericMethod(
                            state.MaterializeCollectionNavigation.ClrType,
                            entityType),
                        result,
                        Expression.Constant(state.MaterializeCollectionNavigation));
                }

                if (navigationExpansionExpression.Type != result.Type && navigationExpansionExpression.Type.IsGenericType)
                {
                    if (navigationExpansionExpression.Type.GetGenericTypeDefinition() == typeof(IOrderedQueryable <>))
                    {
                        var toOrderedQueryableMethodInfo = ToOrderedQueryableMethod.MakeGenericMethod(parameter.Type);

                        return(Expression.Call(toOrderedQueryableMethodInfo, result));
                    }
                    else if (navigationExpansionExpression.Type.GetGenericTypeDefinition() == typeof(IOrderedEnumerable <>))
                    {
                        var toOrderedEnumerableMethodInfo = ToOrderedEnumerableMethod.MakeGenericMethod(parameter.Type);

                        return(Expression.Call(toOrderedEnumerableMethodInfo, result));
                    }
                }

                return(result);
            }

            return(base.VisitExtension(extensionExpression));
        }
示例#2
0
        protected override Expression VisitExtension(Expression extensionExpression)
        {
            switch (extensionExpression)
            {
            case NavigationBindingExpression navigationBindingExpression:
                return(navigationBindingExpression.RootParameter.BuildPropertyAccess(
                           navigationBindingExpression.NavigationTreeNode.ToMapping));

            case NavigationExpansionRootExpression navigationExpansionRootExpression:
                return(Visit(navigationExpansionRootExpression.Unwrap()));

            case NavigationExpansionExpression navigationExpansionExpression:
            {
                var(result, state) = ApplyIncludes(navigationExpansionExpression);
                result             = Visit(result);

                if (!state.ApplyPendingSelector &&
                    state.PendingOrderings.Count == 0 &&
                    state.PendingCardinalityReducingOperator == null &&
                    state.MaterializeCollectionNavigation == null)
                {
                    return(result);
                }

                var parameterType = result.Type.GetSequenceType();

                foreach (var pendingOrdering in state.PendingOrderings)
                {
                    var remappedKeySelectorBody = new ExpressionReplacingVisitor(pendingOrdering.keySelector.Parameters[0], state.CurrentParameter).Visit(pendingOrdering.keySelector.Body);
                    var newSelectorBody         = new NavigationPropertyUnbindingVisitor(state.CurrentParameter).Visit(remappedKeySelectorBody);
                    var newSelector             = Expression.Lambda(newSelectorBody, state.CurrentParameter);
                    var orderingMethod          = pendingOrdering.method.MakeGenericMethod(state.CurrentParameter.Type, newSelectorBody.Type);
                    result = Expression.Call(orderingMethod, result, newSelector);
                }

                if (state.ApplyPendingSelector)
                {
                    var pendingSelector         = (LambdaExpression) new NavigationPropertyUnbindingVisitor(state.CurrentParameter).Visit(state.PendingSelector);
                    var pendingSelectorBodyType = pendingSelector.Type.GetGenericArguments()[1];

                    var pendingSelectMethod = result.Type.IsGenericType && (result.Type.GetGenericTypeDefinition() == typeof(IEnumerable <>) || result.Type.GetGenericTypeDefinition() == typeof(IOrderedEnumerable <>))
                                ? LinqMethodHelpers.EnumerableSelectMethodInfo.MakeGenericMethod(parameterType, pendingSelectorBodyType)
                                : LinqMethodHelpers.QueryableSelectMethodInfo.MakeGenericMethod(parameterType, pendingSelectorBodyType);

                    result        = Expression.Call(pendingSelectMethod, result, pendingSelector);
                    parameterType = result.Type.GetSequenceType();
                }

                if (state.PendingCardinalityReducingOperator != null)
                {
                    result = Expression.Call(state.PendingCardinalityReducingOperator, result);
                }

                if (state.MaterializeCollectionNavigation != null)
                {
                    result = new MaterializeCollectionNavigationExpression(result, state.MaterializeCollectionNavigation);
                }

                if (navigationExpansionExpression.Type != result.Type && navigationExpansionExpression.Type.IsGenericType)
                {
                    if (navigationExpansionExpression.Type.GetGenericTypeDefinition() == typeof(IOrderedQueryable <>))
                    {
                        var toOrderedQueryableMethodInfo = ToOrderedQueryableMethod.MakeGenericMethod(parameterType);

                        return(Expression.Call(toOrderedQueryableMethodInfo, result));
                    }

                    if (navigationExpansionExpression.Type.GetGenericTypeDefinition() == typeof(IOrderedEnumerable <>))
                    {
                        var toOrderedEnumerableMethodInfo = ToOrderedEnumerableMethod.MakeGenericMethod(parameterType);

                        return(Expression.Call(toOrderedEnumerableMethodInfo, result));
                    }
                }

                return(result);
            }
            }

            return(base.VisitExtension(extensionExpression));
        }