internal static bool TryRewrite(DbQueryCommandTree tree, Span span, MergeOption mergeOption, AliasGenerator aliasGenerator, out DbExpression newQuery, out SpanIndex spanInfo)
        {
            newQuery = null;
            spanInfo = null;

            ObjectSpanRewriter rewriter = null;
            bool requiresRelationshipSpan = Span.RequiresRelationshipSpan(mergeOption);

            // Potentially perform a rewrite for span.
            // Note that the public 'Span' property is NOT used to retrieve the Span instance
            // since this forces creation of a Span object that may not be required.
            if (span != null && span.SpanList.Count > 0)
            {
                rewriter = new ObjectFullSpanRewriter(tree, tree.Query, span, aliasGenerator);
            }
            else if (requiresRelationshipSpan)
            {
                rewriter = new ObjectSpanRewriter(tree, tree.Query, aliasGenerator);
            }

            if (rewriter != null)
            {
                rewriter.RelationshipSpan = requiresRelationshipSpan;
                newQuery = rewriter.RewriteQuery();
                if (newQuery != null)
                {
                    Debug.Assert(rewriter.SpanIndex != null || tree.Query.ResultType.EdmEquals(newQuery.ResultType), "Query was rewritten for Span but no SpanIndex was created?");
                    spanInfo = rewriter.SpanIndex;
                }
            }

            return (spanInfo != null);
        }
        /// <summary>
        /// Constructs a new ObjectSpanRewriter that will attempt to apply spanning to the specified query
        /// (represented as a DbExpression) when <see cref="RewriteQuery"/> is called.
        /// </summary>
        /// <param name="toRewrite">A <see cref="DbExpression"/> representing the query to span.</param>
        internal ObjectSpanRewriter(DbCommandTree tree, DbExpression toRewrite, AliasGenerator aliasGenerator)
        {
            Debug.Assert(toRewrite != null, "Expression to rewrite cannot be null");

            _toRewrite = toRewrite;
            _tree = tree;
            _aliasGenerator = aliasGenerator;
        }
        internal ObjectFullSpanRewriter(DbCommandTree tree, DbExpression toRewrite, Span span, AliasGenerator aliasGenerator)
            : base(tree, toRewrite, aliasGenerator)
        {
            Debug.Assert(span != null, "Span cannot be null");
            Debug.Assert(span.SpanList.Count > 0, "At least one span path is required");

            // Retrieve the effective 'T' of the ObjectQuery<T> that produced
            // the Command Tree that is being rewritten. This could be either
            // literally 'T' or Collection<T>.
            EntityType entityType = null;
            if (!TryGetEntityType(this.Query.ResultType, out entityType))
            {
                // If the result type of the query is neither an Entity type nor a collection
                // type with an Entity element type, then full Span is currently not allowed.
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.ObjectQuery_Span_IncludeRequiresEntityOrEntityCollection);
            }

            // Construct the SpanPathInfo navigation property tree using the
            // list of Include Span paths from the Span object:
            // Create a SpanPathInfo instance that represents the root of the tree
            // and takes its Entity type from the Entity type of the result type of the query.
            SpanPathInfo spanRoot = new SpanPathInfo(entityType);
            
            // Populate the tree of navigation properties based on the navigation property names
            // in the Span paths from the Span object. Commonly rooted span paths are merged, so
            // that paths of "Customer.Order" and "Customer.Address", for example, will share a
            // common SpanPathInfo for "Customer" in the Children collection of the root SpanPathInfo,
            // and that SpanPathInfo will contain one child for "Order" and another for "Address".
            foreach (Span.SpanPath path in span.SpanList)
            {
                AddSpanPath(spanRoot, path.Navigations);
            }

            // The 'current' span path is initialized to the root of the Include span tree
            _currentSpanPath.Push(spanRoot);
        }
 private RelationshipNavigationVisitor(AliasGenerator aliasGenerator)
 {
     _aliasGenerator = aliasGenerator;
 }
            internal static DbExpression FindNavigationExpression(DbExpression expression, AliasGenerator aliasGenerator, out NavigationInfo navInfo)
            {
                Debug.Assert(TypeSemantics.IsCollectionType(expression.ResultType), "Non-collection input to projection?");

                navInfo = null;

                TypeUsage elementType = ((CollectionType)expression.ResultType.EdmType).TypeUsage;
                if (!TypeSemantics.IsEntityType(elementType) && !TypeSemantics.IsReferenceType(elementType))
                {
                    return expression;
                }

                RelationshipNavigationVisitor visitor = new RelationshipNavigationVisitor(aliasGenerator);
                DbExpression rewrittenExpression = visitor.Find(expression);
                if (!object.ReferenceEquals(expression, rewrittenExpression))
                {
                    Debug.Assert(visitor._original != null && visitor._rewritten != null, "Expression was rewritten but no navigation was found?");
                    navInfo = new NavigationInfo(visitor._original, visitor._rewritten);
                    return rewrittenExpression;
                }
                else
                {
                    return expression;
                }
            }
 /// <summary>
 /// Returns a lifter instance which supports lifting the intrinsic order of the given
 /// source expression across specific operations (filter, project, oftype, skip, and limit)
 /// </summary>
 /// <remarks>
 /// Lifting only occurs for expressions that are ordered. Each of the nested
 /// OrderByLifterBase class implementations represents one or two of the ordered patterns with
 /// the exception of the PassthroughOrderByLifter. The latter class represents expressions
 /// without intrinsic order that therefore require no lifting.
 /// </remarks>
 internal static OrderByLifterBase GetLifter(DbExpression source, AliasGenerator aliasGenerator)
 {
     if (source.ExpressionKind == DbExpressionKind.Sort)
     {
         return new SortLifter((DbSortExpression)source, aliasGenerator);
     }
     if (source.ExpressionKind == DbExpressionKind.Project)
     {
         var project = (DbProjectExpression)source;
         DbExpression projectInput = project.Input.Expression;
         if (projectInput.ExpressionKind == DbExpressionKind.Sort)
         {
             return new ProjectSortLifter(project, (DbSortExpression)projectInput, aliasGenerator);
         }
         if (projectInput.ExpressionKind == DbExpressionKind.Skip)
         {
             return new ProjectSkipLifter(project, (DbSkipExpression)projectInput, aliasGenerator);
         }
         if (projectInput.ExpressionKind == DbExpressionKind.Limit)
         {
             var limit = (DbLimitExpression)projectInput;
             DbExpression limitInput = limit.Argument;
             if (limitInput.ExpressionKind == DbExpressionKind.Sort)
             {
                 return new ProjectLimitSortLifter(project, limit, (DbSortExpression)limitInput, aliasGenerator);
             }
             if (limitInput.ExpressionKind == DbExpressionKind.Skip)
             {
                 return new ProjectLimitSkipLifter(project, limit, (DbSkipExpression)limitInput, aliasGenerator);
             }
         }
     }
     if (source.ExpressionKind == DbExpressionKind.Skip)
     {
         return new SkipLifter((DbSkipExpression)source, aliasGenerator);
     }
     if (source.ExpressionKind == DbExpressionKind.Limit)
     {
         var limit = (DbLimitExpression)source;
         DbExpression limitInput = limit.Argument;
         if (limitInput.ExpressionKind == DbExpressionKind.Sort)
         {
             return new LimitSortLifter(limit, (DbSortExpression)limitInput, aliasGenerator);
         }
         if (limitInput.ExpressionKind == DbExpressionKind.Skip)
         {
             return new LimitSkipLifter(limit, (DbSkipExpression)limitInput, aliasGenerator);
         }
         if (limitInput.ExpressionKind == DbExpressionKind.Project)
         {
             var project = (DbProjectExpression)limitInput;
             DbExpression projectInput = project.Input.Expression;
             if (projectInput.ExpressionKind == DbExpressionKind.Sort)
             {
                 // source.Sort(o).Project(p).Limit(k).* is equivalent to transformation for 
                 // source.Sort(o).Limit(k).Project(p).* 
                 return new ProjectLimitSortLifter(project, limit, (DbSortExpression)projectInput, aliasGenerator);
             }
             if (projectInput.ExpressionKind == DbExpressionKind.Skip)
             {
                 // source.Skip(k, o).Project(p).Limit(k2).* is equivalent to transformation for 
                 // source.Skip(k, o).Limit(k2).Project(p).*
                 return new ProjectLimitSkipLifter(project, limit, (DbSkipExpression)projectInput, aliasGenerator);
             }
         }
     }
     return new PassthroughOrderByLifter(source, aliasGenerator);
 }
 protected OrderByLifterBase(DbExpression root, AliasGenerator aliasGenerator)
 {
     _root = root;
     _aliasGenerator = aliasGenerator;
 }
 internal PassthroughOrderByLifter(DbExpression source, AliasGenerator aliasGenerator)
     : base(source, aliasGenerator)
 {
 }
 internal SortLifter(DbSortExpression sort, AliasGenerator aliasGenerator)
     : base(sort, aliasGenerator)
 {
     _sort = sort;
     _source = sort.Input.Expression;
 }
 internal ProjectSortLifter(DbProjectExpression project, DbSortExpression sort, AliasGenerator aliasGenerator)
     : base(project, aliasGenerator)
 {
     _project = project;
     _sort = sort;
     _source = sort.Input.Expression;
 }
 internal SkipLifter(DbSkipExpression skip, AliasGenerator aliasGenerator)
     : base(skip, aliasGenerator)
 {
     _skip = skip;
     _source = skip.Input.Expression;
 }
 internal ProjectSkipLifter(DbProjectExpression project, DbSkipExpression skip, AliasGenerator aliasGenerator)
     : base(project, aliasGenerator)
 {
     _project = project;
     _skip = skip;
     _source = _skip.Input.Expression;
 }
 internal OrderByLifter(AliasGenerator aliasGenerator)
 {
     _aliasGenerator = aliasGenerator;
 }
 internal LimitSortLifter(DbLimitExpression limit, DbSortExpression sort, AliasGenerator aliasGenerator)
     : base(limit, aliasGenerator)
 {
     _limit = limit;
     _sort = sort;
     _source = sort.Input.Expression;
 }
 internal LimitSkipLifter(DbLimitExpression limit, DbSkipExpression skip, AliasGenerator aliasGenerator)
     : base(limit, aliasGenerator)
 {
     _limit = limit;
     _skip = skip;
     _source = skip.Input.Expression;
 }
 internal ProjectLimitSortLifter(
     DbProjectExpression project, DbLimitExpression limit, DbSortExpression sort, AliasGenerator aliasGenerator)
     : base(project, aliasGenerator)
 {
     _project = project;
     _limit = limit;
     _sort = sort;
 }