Ejemplo n.º 1
0
        internal static Expression Bind(DataAccessModel dataAccessModel, SqlDataTypeProvider sqlDataTypeProvider, Expression expression)
        {
            var placeholderCount = -1;

            expression = Evaluator.PartialEval(expression, ref placeholderCount);
            expression = QueryBinder.Bind(dataAccessModel, expression);
            expression = SqlEnumTypeNormalizer.Normalize(expression, sqlDataTypeProvider.GetTypeForEnums());
            expression = Evaluator.PartialEval(expression, ref placeholderCount);
            expression = SqlNullComparisonCoalescer.Coalesce(expression);
            expression = SqlTupleOrAnonymousTypeComparisonExpander.Expand(expression);
            expression = SqlObjectOperandComparisonExpander.Expand(expression);
            expression = SqlRedundantFunctionCallRemover.Remove(expression);

            return(expression);
        }
Ejemplo n.º 2
0
        public static Expression Optimize(Expression expression, Type typeForEnums, bool simplerPartialVal = true)
        {
            expression = SqlObjectOperandComparisonExpander.Expand(expression);
            expression = SqlEnumTypeNormalizer.Normalize(expression, typeForEnums);
            expression = SqlGroupByCollator.Collate(expression);
            expression = SqlAggregateSubqueryRewriter.Rewrite(expression);
            expression = SqlUnusedColumnRemover.Remove(expression);
            expression = SqlRedundantColumnRemover.Remove(expression);
            expression = SqlRedundantSubqueryRemover.Remove(expression);
            expression = SqlFunctionCoalescer.Coalesce(expression);
            expression = SqlExistsSubqueryOptimizer.Optimize(expression);
            expression = SqlRedundantBinaryExpressionsRemover.Remove(expression);
            expression = SqlCrossJoinRewriter.Rewrite(expression);

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

            expression = SqlRedundantFunctionCallRemover.Remove(expression);
            expression = SqlConditionalEliminator.Eliminate(expression);
            expression = SqlExpressionCollectionOperationsExpander.Expand(expression);
            expression = SqlSumAggregatesDefaultValueCoalescer.Coalesce(expression);
            expression = SqlOrderByRewriter.Rewrite(expression);

            var rewritten = SqlCrossApplyRewriter.Rewrite(expression);

            if (rewritten != expression)
            {
                expression = rewritten;

                expression = SqlUnusedColumnRemover.Remove(expression);
                expression = SqlRedundantColumnRemover.Remove(expression);
                expression = SqlRedundantSubqueryRemover.Remove(expression);
                expression = SqlOrderByRewriter.Rewrite(expression);
            }

            return(expression);
        }
Ejemplo n.º 3
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 = SqlRedundantFunctionCallRemover.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 = SqlRedundantFunctionCallRemover.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 = SqlRedundantFunctionCallRemover.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));
            }
        }