Example #1
0
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            var oldParentSelector = _parentSelector;

            _parentSelector = expression.QueryModel.SelectClause.Selector;

            expression.QueryModel.TransformExpressions(Visit);

            _parentSelector = oldParentSelector;

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

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

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

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

            return(expression);
        }
        /// <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>
        public EagerLoadingExpressionVisitor(
            QueryCompilationContext queryCompilationContext,
            IQuerySourceTracingExpressionVisitorFactory querySourceTracingExpressionVisitorFactory)
        {
            _queryCompilationContext = queryCompilationContext;

            _querySourceTracingExpressionVisitor = querySourceTracingExpressionVisitorFactory.Create();
        }
        /// <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);
        }