Esempio n. 1
0
        public static Expression Optimize(Expression expression, Type typeForEnums, bool simplerPartialVal = true)
        {
            expression = ObjectOperandComparisonExpander.Expand(expression);
            expression = EnumTypeNormalizer.Normalize(expression, typeForEnums);
            expression = GroupByCollator.Collate(expression);
            expression = AggregateSubqueryRewriter.Rewrite(expression);
            expression = UnusedColumnRemover.Remove(expression);
            expression = RedundantColumnRemover.Remove(expression);
            expression = RedundantSubqueryRemover.Remove(expression);
            expression = FunctionCoalescer.Coalesce(expression);
            expression = ExistsSubqueryOptimizer.Optimize(expression);
            expression = RedundantBinaryExpressionsRemover.Remove(expression);

            if (simplerPartialVal)
            {
                expression = Evaluator.PartialEval(expression, c => c.NodeType != (ExpressionType)SqlExpressionType.ConstantPlaceholder && Evaluator.CanBeEvaluatedLocally(c));
            }
            else
            {
                expression = Evaluator.PartialEval(expression);
            }

            expression = RedundantFunctionCallRemover.Remove(expression);
            expression = ConditionalEliminator.Eliminate(expression);
            expression = SqlExpressionCollectionOperationsExpander.Expand(expression);
            expression = SumAggregatesDefaultValueCoalescer.Coalesce(expression);
            expression = OrderByRewriter.Rewrite(expression);

            return(expression);
        }
Esempio n. 2
0
        protected virtual FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionExpression)
        {
            var function  = functionExpression.Function;
            var arguments = functionExpression.Arguments;

            switch (function)
            {
            case SqlFunction.IsNull:
                return(new FunctionResolveResult("", true, arguments)
                {
                    functionSuffix = " IS NULL"
                });

            case SqlFunction.IsNotNull:
                return(new FunctionResolveResult("", true, arguments)
                {
                    functionSuffix = " IS NOT NULL"
                });

            case SqlFunction.In:
                return(new FunctionResolveResult("IN", true, arguments));

            case SqlFunction.Exists:
                return(new FunctionResolveResult("EXISTSOPERATOR", true, arguments)
                {
                    functionPrefix = " EXISTS "
                });

            case SqlFunction.UserDefined:
                return(new FunctionResolveResult(functionExpression.UserDefinedFunctionName, false, arguments));

            case SqlFunction.Coalesce:
                return(new FunctionResolveResult("COALESCE", false, arguments));

            case SqlFunction.Like:
                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, arguments));

            case SqlFunction.CompareObject:
                var expressionType = (ExpressionType)((ConstantExpression)arguments[0]).Value;
                var args           = new Expression[2];

                args[0] = arguments[1];
                args[1] = arguments[2];

                switch (expressionType)
                {
                case ExpressionType.LessThan:
                    return(new FunctionResolveResult("<", true, args.ToReadOnlyList()));

                case ExpressionType.LessThanOrEqual:
                    return(new FunctionResolveResult("<=", true, args.ToReadOnlyList()));

                case ExpressionType.GreaterThan:
                    return(new FunctionResolveResult(">", true, args.ToReadOnlyList()));

                case ExpressionType.GreaterThanOrEqual:
                    return(new FunctionResolveResult(">=", true, args.ToReadOnlyList()));
                }
                throw new InvalidOperationException();

            case SqlFunction.NotLike:
                return(new FunctionResolveResult("NOT " + this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, arguments));

            case SqlFunction.ServerNow:
                return(new FunctionResolveResult("NOW", false, arguments));

            case SqlFunction.ServerUtcNow:
                return(new FunctionResolveResult("UTCNOW", false, arguments));

            case SqlFunction.StartsWith:
            {
                Expression newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[1], Expression.Constant("%"));
                newArgument = RedundantFunctionCallRemover.Remove(newArgument);

                var list = new List <Expression>
                {
                    arguments[0],
                    newArgument
                };

                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyList()));
            }

            case SqlFunction.ContainsString:
            {
                Expression newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[1], Expression.Constant("%"));
                newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Constant("%"), newArgument);
                newArgument = RedundantFunctionCallRemover.Remove(newArgument);

                var list = new List <Expression>
                {
                    arguments[0],
                    newArgument
                };

                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyList()));
            }

            case SqlFunction.EndsWith:
            {
                Expression newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Constant("%"), arguments[1]);
                newArgument = RedundantFunctionCallRemover.Remove(newArgument);

                var list = new List <Expression>
                {
                    arguments[0],
                    newArgument
                };

                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyList()));
            }

            default:
                return(new FunctionResolveResult(function.ToString().ToUpper(), false, arguments));
            }
        }