public override Expression Visit(
            [NotNull] Expression expression)
        {
            var currentExpression = expression;
            var inExpressionOptimized =
                new EqualityPredicateInExpressionOptimizer().Visit(currentExpression);

            currentExpression = inExpressionOptimized;

            var negationOptimized1 =
                new PredicateNegationExpressionOptimizer()
                    .Visit(currentExpression);

            currentExpression = negationOptimized1;

            var equalityExpanded =
                new EqualityPredicateExpandingVisitor().Visit(currentExpression);

            currentExpression = equalityExpanded;

            var negationOptimized2 =
                new PredicateNegationExpressionOptimizer()
                    .Visit(currentExpression);

            currentExpression = negationOptimized2;

            var parameterDectector = new ParameterExpressionDetectingVisitor();
            parameterDectector.Visit(currentExpression);

            if (!parameterDectector.ContainsParameters
                && !_useRelationalNullSemantics)
            {
                var optimizedNullExpansionVisitor = new NullSemanticsOptimizedExpandingVisitor();
                var nullSemanticsExpandedOptimized = optimizedNullExpansionVisitor.Visit(currentExpression);
                if (optimizedNullExpansionVisitor.OptimizedExpansionPossible)
                {
                    currentExpression = nullSemanticsExpandedOptimized;
                }
                else
                {
                    currentExpression = new NullSemanticsExpandingVisitor()
                        .Visit(currentExpression);
                }
            }

            if (_useRelationalNullSemantics)
            {
                currentExpression = new NotNullableExpression(currentExpression);
            }

            var negationOptimized3 =
                new PredicateNegationExpressionOptimizer()
                    .Visit(currentExpression);

            currentExpression = negationOptimized3;

            return currentExpression;
        }
コード例 #2
0
        public virtual Expression VisitSelect(SelectExpression selectExpression)
        {
            Check.NotNull(selectExpression, nameof(selectExpression));

            IDisposable subQueryIndent = null;

            if (selectExpression.Alias != null)
            {
                _sql.AppendLine("(");

                subQueryIndent = _sql.Indent();
            }

            _sql.Append("SELECT ");

            if (selectExpression.IsDistinct)
            {
                _sql.Append("DISTINCT ");
            }

            GenerateTop(selectExpression);

            if (selectExpression.Projection.Any())
            {
                VisitJoin(selectExpression.Projection);
            }
            else if (selectExpression.IsProjectStar)
            {
                _sql.Append(DelimitIdentifier(selectExpression.Tables.Single().Alias))
                .Append(".*");
            }
            else
            {
                _sql.Append("1");
            }

            if (selectExpression.Tables.Any())
            {
                _sql.AppendLine()
                .Append("FROM ");

                VisitJoin(selectExpression.Tables, sql => sql.AppendLine());
            }

            if (selectExpression.Predicate != null)
            {
                _sql.AppendLine()
                .Append("WHERE ");

                var constantExpression = selectExpression.Predicate as ConstantExpression;

                if (constantExpression != null)
                {
                    _sql.Append((bool)constantExpression.Value ? "1 = 1" : "1 = 0");
                }
                else
                {
                    var predicate
                        = new NullComparisonTransformingVisitor(_parameterValues)
                          .Visit(selectExpression.Predicate);

                    // we have to optimize out comparisons to null-valued parameters before we can expand null semantics
                    if (_parameterValues.Count > 0)
                    {
                        var optimizedNullExpansionVisitor  = new NullSemanticsOptimizedExpandingVisitor();
                        var nullSemanticsExpandedOptimized = optimizedNullExpansionVisitor.Visit(predicate);
                        if (optimizedNullExpansionVisitor.OptimizedExpansionPossible)
                        {
                            predicate = nullSemanticsExpandedOptimized;
                        }
                        else
                        {
                            predicate = new NullSemanticsExpandingVisitor()
                                        .Visit(predicate);
                        }
                    }

                    predicate = new ReducingExpressionVisitor().Visit(predicate);

                    Visit(predicate);

                    if (selectExpression.Predicate is ParameterExpression ||
                        selectExpression.Predicate.IsAliasWithColumnExpression() ||
                        selectExpression.Predicate is SelectExpression)
                    {
                        _sql.Append(" = ");
                        _sql.Append(TrueLiteral);
                    }
                }
            }

            if (selectExpression.OrderBy.Any())
            {
                _sql.AppendLine()
                .Append("ORDER BY ");

                VisitJoin(selectExpression.OrderBy, t =>
                {
                    var aliasExpression = t.Expression as AliasExpression;

                    if (aliasExpression != null)
                    {
                        if (aliasExpression.Alias != null)
                        {
                            var columnExpression = aliasExpression.TryGetColumnExpression();

                            if (columnExpression != null)
                            {
                                _sql.Append(DelimitIdentifier(columnExpression.TableAlias))
                                .Append(".");
                            }

                            _sql.Append(DelimitIdentifier(aliasExpression.Alias));
                        }
                        else
                        {
                            Visit(aliasExpression.Expression);
                        }
                    }
                    else
                    {
                        Visit(t.Expression);
                    }

                    if (t.OrderingDirection == OrderingDirection.Desc)
                    {
                        _sql.Append(" DESC");
                    }
                });
            }

            GenerateLimitOffset(selectExpression);

            if (subQueryIndent != null)
            {
                subQueryIndent.Dispose();

                _sql.AppendLine()
                .Append(")");

                if (selectExpression.Alias.Length > 0)
                {
                    _sql.Append(" AS ")
                    .Append(DelimitIdentifier(selectExpression.Alias));
                }
            }

            return(selectExpression);
        }