Example #1
0
        protected virtual void IncludeNavigations(
            [NotNull] QueryModel queryModel,
            [NotNull] IReadOnlyCollection <IncludeSpecification> includeSpecifications)
        {
            Check.NotNull(queryModel, nameof(queryModel));
            Check.NotNull(includeSpecifications, nameof(includeSpecifications));

            var querySourceTracingExpressionVisitor
                = new QuerySourceTracingExpressionVisitor();

            foreach (var includeSpecification in includeSpecifications)
            {
                var resultQuerySourceReferenceExpression
                    = querySourceTracingExpressionVisitor
                      .FindResultQuerySourceReferenceExpression(
                          queryModel.SelectClause.Selector,
                          includeSpecification.QuerySource);

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

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

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

                    QueryCompilationContext
                    .AddTrackableInclude(
                        resultQuerySourceReferenceExpression.ReferencedQuerySource,
                        includeSpecification.NavigationPath);
                }
            }
        }
        protected override Expression VisitSubQuery(SubQueryExpression subQueryExpression)
        {
            Check.NotNull(subQueryExpression, nameof(subQueryExpression));

            subQueryExpression.QueryModel.TransformExpressions(Visit);

            var querySourceReferenceExpression
                = subQueryExpression.QueryModel.SelectClause.Selector
                    as QuerySourceReferenceExpression;

            if (querySourceReferenceExpression != null)
            {
                var querySourceTracingExpressionVisitor = new QuerySourceTracingExpressionVisitor();

                var resultQuerySource
                    = querySourceTracingExpressionVisitor
                        .FindResultQuerySourceReferenceExpression(
                            _parentSelector,
                            querySourceReferenceExpression.ReferencedQuerySource);

                if (resultQuerySource == null)
                {
                    _querySources[querySourceReferenceExpression.ReferencedQuerySource]--;
                }
            }

            return subQueryExpression;
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used 
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            var oldParentSelector = _selector;
            var oldQueryModel = _queryModel;

            _selector = expression.QueryModel.SelectClause.Selector;
            _queryModel = expression.QueryModel;

            _queryModel.TransformExpressions(Visit);

            _selector = oldParentSelector;
            _queryModel = oldQueryModel;

            var querySourceReferenceExpression
                = expression.QueryModel.SelectClause.Selector
                    as QuerySourceReferenceExpression;

            if (querySourceReferenceExpression != null)
            {
                var querySourceTracingExpressionVisitor = new QuerySourceTracingExpressionVisitor();

                if (expression.QueryModel.ResultOperators.LastOrDefault() is DefaultIfEmptyResultOperator)
                {
                    var underlyingQuerySource = (((querySourceReferenceExpression.ReferencedQuerySource as MainFromClause)
                        ?.FromExpression as QuerySourceReferenceExpression)
                        ?.ReferencedQuerySource as GroupJoinClause)?.JoinClause;

                    if (underlyingQuerySource != null)
                    {
                        AddQuerySource(underlyingQuerySource);
                    }
                }

                var resultQuerySource
                    = querySourceTracingExpressionVisitor
                        .FindResultQuerySourceReferenceExpression(
                            _selector,
                            querySourceReferenceExpression.ReferencedQuerySource);

                if ((resultQuerySource == null)
                    && !(expression.QueryModel.ResultOperators.LastOrDefault() is OfTypeResultOperator))
                {
                    _querySources[querySourceReferenceExpression.ReferencedQuerySource]--;
                }

                foreach (var sourceExpression in _queryModel.ResultOperators.Select(SetResultOperationSourceExpression).Where(e => e != null))
                {
                    if (sourceExpression.Equals(expression))
                    {
                        var parentQuerySource = _selector as QuerySourceReferenceExpression;
                        if ((parentQuerySource != null)
                            && (_querySources[parentQuerySource.ReferencedQuerySource] > 0)
                            && (parentQuerySource.Type == querySourceReferenceExpression.Type))
                        {
                            _querySources[querySourceReferenceExpression.ReferencedQuerySource]++;
                        }
                    }
                }
            }

            return expression;
        }
        protected override Expression VisitSubQuery(SubQueryExpression subQueryExpression)
        {
            var oldParentSelector = _parentSelector;

            _parentSelector = subQueryExpression.QueryModel.SelectClause.Selector;

            subQueryExpression.QueryModel.TransformExpressions(Visit);

            _parentSelector = oldParentSelector;

            var querySourceReferenceExpression
                = subQueryExpression.QueryModel.SelectClause.Selector
                    as QuerySourceReferenceExpression;

            if (querySourceReferenceExpression != null)
            {
                var querySourceTracingExpressionVisitor = new QuerySourceTracingExpressionVisitor();

                var resultQuerySource
                    = querySourceTracingExpressionVisitor
                        .FindResultQuerySourceReferenceExpression(
                            _parentSelector,
                            querySourceReferenceExpression.ReferencedQuerySource);

                if (resultQuerySource == null
                    && !(subQueryExpression.QueryModel.ResultOperators.LastOrDefault() is OfTypeResultOperator))
                {
                    _querySources[querySourceReferenceExpression.ReferencedQuerySource]--;
                }
            }

            return subQueryExpression;
        }