protected virtual void IncludeNavigations([NotNull] QueryModel queryModel)
        {
            Check.NotNull(queryModel, nameof(queryModel));

            var includeSpecifications
                = QueryCompilationContext.QueryAnnotations
                  .OfType <IncludeQueryAnnotation>()
                  .Select(annotation =>
            {
                var navigationPath
                    = BindNavigationPathMemberExpression(
                          (MemberExpression)annotation.NavigationPropertyPath,
                          (ns, _) => BindChainedNavigations(ns, annotation.ChainedNavigationProperties).ToArray());

                if (navigationPath == null)
                {
                    throw new InvalidOperationException(
                        Strings.IncludeNonBindableExpression(annotation.NavigationPropertyPath));
                }

                return(new IncludeSpecification(annotation.QuerySource, navigationPath));
            })
                  .ToList();

            var querySourceTracingExpressionTreeVisitor
                = new QuerySourceTracingExpressionTreeVisitor();

            foreach (var includeSpecification in includeSpecifications
                     .OrderBy(a => a.NavigationPath.First().PointsToPrincipal()))
            {
                var resultQuerySourceReferenceExpression
                    = querySourceTracingExpressionTreeVisitor
                      .FindResultQuerySourceReferenceExpression(
                          queryModel.SelectClause.Selector,
                          includeSpecification.QuerySource);

                if (resultQuerySourceReferenceExpression != null)
                {
                    var accessorLambda
                        = AccessorFindingExpressionTreeVisitor
                          .FindAccessorLambda(
                              resultQuerySourceReferenceExpression,
                              queryModel.SelectClause.Selector,
                              Expression.Parameter(queryModel.SelectClause.Selector.Type));

                    QueryCompilationContext.Logger
                    .LogInformation(
                        includeSpecification.NavigationPath.Join("."),
                        Strings.LogIncludingNavigation);

                    IncludeNavigations(
                        includeSpecification.QuerySource,
                        _expression.Type.GetSequenceType(),
                        accessorLambda,
                        includeSpecification.NavigationPath,
                        QuerySourceRequiresTracking(includeSpecification.QuerySource));

                    QueryCompilationContext
                    .AddTrackableInclude(
                        resultQuerySourceReferenceExpression.ReferencedQuerySource,
                        includeSpecification.NavigationPath);
                }
            }
        }
示例#2
0
        protected virtual void IncludeNavigations(
            [NotNull] QueryModel queryModel,
            [NotNull] Type resultType)
        {
            Check.NotNull(queryModel, "queryModel");
            Check.NotNull(resultType, "resultType");

            var querySourceTracingExpressionTreeVisitor
                = new QuerySourceTracingExpressionTreeVisitor();

            foreach (var include
                     in from queryAnnotation in _queryAnnotations
                     let includeResultOperator = queryAnnotation.ResultOperator as IncludeResultOperator
                                                 where includeResultOperator != null
                                                 let navigationPath
                                                     = BindNavigationPathMemberExpression(
                                                           (MemberExpression)includeResultOperator.NavigationPropertyPath,
                                                           (ns, _) => BindChainedNavigations(ns, includeResultOperator.ChainedNavigationProperties).ToArray())
                                                       orderby navigationPath != null &&
                                                       navigationPath.First().PointsToPrincipal
                                                       select new
            {
                navigationPath,
                queryAnnotation.QuerySource,
                includeResultOperator.NavigationPropertyPath
            })
            {
                if (include.navigationPath != null)
                {
                    var resultQuerySourceReferenceExpression
                        = querySourceTracingExpressionTreeVisitor
                          .FindResultQuerySourceReferenceExpression(
                              queryModel.SelectClause.Selector,
                              include.QuerySource);

                    if (resultQuerySourceReferenceExpression != null)
                    {
                        var accessorLambda
                            = AccessorFindingExpressionTreeVisitor
                              .FindAccessorLambda(
                                  resultQuerySourceReferenceExpression,
                                  queryModel.SelectClause.Selector,
                                  Expression.Parameter(queryModel.SelectClause.Selector.Type));

                        QueryCompilationContext.Logger
                        .WriteInformation(
                            include.navigationPath.Join("."),
                            Strings.LogIncludingNavigation);

                        IncludeNavigations(
                            include.QuerySource,
                            resultType,
                            accessorLambda,
                            include.navigationPath);
                    }
                }
                else
                {
                    throw new InvalidOperationException(
                              Strings.IncludeNonBindableExpression(include.NavigationPropertyPath));
                }
            }
        }
        protected virtual void IncludeNavigations(
            [NotNull] QueryModel queryModel,
            [NotNull] Type resultType,
            [NotNull] ICollection <QueryAnnotation> queryAnnotations)
        {
            Check.NotNull(queryModel, "queryModel");
            Check.NotNull(resultType, "resultType");
            Check.NotNull(queryAnnotations, "queryAnnotations");

            var querySourceTracingExpressionTreeVisitor
                = new QuerySourceTracingExpressionTreeVisitor();

            foreach (var queryAnnotation in queryAnnotations)
            {
                var includeResultOperator
                    = queryAnnotation.ResultOperator as IncludeResultOperator;

                if (includeResultOperator != null)
                {
                    var navigation
                        = BindNavigationMemberExpression(
                              (MemberExpression)includeResultOperator.NavigationPropertyPath,
                              (n, _) => n);

                    if (navigation != null)
                    {
                        var resultQuerySourceReferenceExpression
                            = querySourceTracingExpressionTreeVisitor
                              .FindResultQuerySourceReferenceExpression(
                                  queryModel.SelectClause.Selector,
                                  queryAnnotation.QuerySource);

                        if (resultQuerySourceReferenceExpression != null)
                        {
                            var accessorLambda
                                = AccessorFindingExpressionTreeVisitor
                                  .FindAccessorLambda(
                                      resultQuerySourceReferenceExpression,
                                      queryModel.SelectClause.Selector,
                                      Expression.Parameter(queryModel.SelectClause.Selector.Type));

                            QueryCompilationContext.Logger
                            .WriteInformation(
                                navigation,
                                Strings.FormatLogIncludingNavigation);

                            IncludeNavigation(
                                queryAnnotation.QuerySource,
                                resultType,
                                accessorLambda,
                                navigation);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException(
                                  Strings.FormatIncludeNonBindableExpression(includeResultOperator.NavigationPropertyPath));
                    }
                }
            }
        }