protected override Expression VisitChildren(ExpressionVisitor visitor)
        {
            var changed = false;

            var projections = new List <ProjectionExpression>();
            IDictionary <ProjectionMember, Expression> projectionMapping;

            if (Projection.Any())
            {
                projectionMapping = _projectionMapping;
                foreach (var item in Projection)
                {
                    var projection = (ProjectionExpression)visitor.Visit(item);
                    projections.Add(projection);

                    changed |= projection != item;
                }
            }
            else
            {
                projectionMapping = new Dictionary <ProjectionMember, Expression>();
                foreach (var mapping in _projectionMapping)
                {
                    var newProjection = visitor.Visit(mapping.Value);
                    changed |= newProjection != mapping.Value;

                    projectionMapping[mapping.Key] = newProjection;
                }
            }

            var fromExpression = (RootReferenceExpression)visitor.Visit(FromExpression);

            changed |= fromExpression != FromExpression;

            var predicate = (SqlExpression)visitor.Visit(Predicate);

            changed |= predicate != Predicate;

            var orderings = new List <OrderingExpression>();

            foreach (var ordering in _orderings)
            {
                var orderingExpression = (SqlExpression)visitor.Visit(ordering.Expression);
                changed |= orderingExpression != ordering.Expression;
                orderings.Add(ordering.Update(orderingExpression));
            }

            var offset = (SqlExpression)visitor.Visit(Offset);

            changed |= offset != Offset;

            var limit = (SqlExpression)visitor.Visit(Limit);

            changed |= limit != Limit;

            if (changed)
            {
                var newSelectExpression = new SelectExpression(projections, fromExpression, orderings)
                {
                    _projectionMapping = projectionMapping,
                    Predicate          = predicate,
                    Offset             = offset,
                    Limit      = limit,
                    IsDistinct = IsDistinct
                };

                return(newSelectExpression);
            }

            return(this);
        }
 protected abstract Expression VisitSelect(SelectExpression selectExpression);