예제 #1
0
        protected override Expression VisitExpression(Expression exp)
        {
            if (exp != null && 
                _canBeSimplified[exp] && 
                !(exp.NodeType == ExpressionType.Lambda) && 
                !(exp.NodeType == ExpressionType.Quote))
            {
                var eval = exp.Evaluate();
                return Expression.Constant(eval, exp.Type);
            }

            return base.VisitExpression(exp);
        }
 protected virtual Expression AnalyzeConstant(Expression expression, BuilderContext builderContext)
 {
     // we try to find a non-constant operand, and if we do, we won't change this expression
     foreach (var operand in expression.GetOperands())
     {
         if (!(operand is ConstantExpression))
             return expression;
     }
     // now, we just simply return a constant with new value
     try
     {
         var optimizedExpression = Expression.Constant(expression.Evaluate());
         // sometimes, optimizing an expression changes its type, and we just can't allow this.
         if (optimizedExpression.Type == expression.Type)
             return optimizedExpression;
     }
         // if we fail to evaluate the expression, then just return it
     catch (ArgumentException) { }
     return expression;
 }
 private Expression AnalyzeBinaryBoolean(Expression expression, BuilderContext builderContext)
 {
     if (expression.Type != typeof(bool))
         return expression;
     var bin = expression as BinaryExpression;
     if (bin == null)
         return expression;
     bool canOptimizeLeft = bin.Left.NodeType == ExpressionType.Constant && bin.Left.Type == typeof(bool);
     bool canOptimizeRight = bin.Right.NodeType == ExpressionType.Constant && bin.Right.Type == typeof(bool);
     if (canOptimizeLeft && canOptimizeRight)
         return Expression.Constant(expression.Evaluate());
     if (canOptimizeLeft || canOptimizeRight)
         switch (expression.NodeType)
         {
             case ExpressionType.AndAlso:
                 if (canOptimizeLeft)
                     if ((bool)bin.Left.Evaluate())
                         return bin.Right;   // (TRUE and X) == X 
                     else
                         return bin.Left;    // (FALSE and X) == FALSE 
                 if (canOptimizeRight)
                     if ((bool)bin.Right.Evaluate())
                         return bin.Left;    // (X and TRUE) == X 
                     else
                         return bin.Right;   // (X and FALSE) == FALSE
                 break;
             case ExpressionType.OrElse:
                 if (canOptimizeLeft)
                     if ((bool)bin.Left.Evaluate())
                         return bin.Left;    // (TRUE or X) == TRUE 
                     else
                         return bin.Right;   // (FALSE or X) == X 
                 if (canOptimizeRight)
                     if ((bool)bin.Right.Evaluate())
                         return bin.Right;   // (X or TRUE) == TRUE 
                     else
                         return bin.Left;    // (X or FALSE) == X
                 break;
             case ExpressionType.Equal:
                 // TODO: this optimization should work for Unary Expression Too
                 // this actually produce errors becouse of string based Sql generation
                 canOptimizeLeft = canOptimizeLeft && bin.Right is BinaryExpression;
                 if (canOptimizeLeft)
                     if ((bool)bin.Left.Evaluate())
                         return bin.Right;                   // (TRUE == X) == X 
                     else
                         return Expression.Not(bin.Right);   // (FALSE == X) == not X 
                 canOptimizeRight = canOptimizeRight && bin.Left is BinaryExpression;
                 // TODO: this optimization should work for Unary Expression Too
                 // this actually produce errors becouse of string based Sql generation
                 if (canOptimizeRight)
                     if ((bool)bin.Right.Evaluate())
                         return bin.Left;                    // (X == TRUE) == X 
                     else
                         return Expression.Not(bin.Left);    // (X == FALSE) == not X
                 break;
             case ExpressionType.NotEqual:
                 canOptimizeLeft = canOptimizeLeft && bin.Right is BinaryExpression;
                 // TODO: this optimization should work for Unary Expression Too
                 // this actually produce errors becouse of string based Sql generation
                 if (canOptimizeLeft)
                     if ((bool)bin.Left.Evaluate())
                         return Expression.Not(bin.Right);   // (TRUE != X) == not X 
                     else
                         return bin.Right;                   // (FALSE != X) == X 
                 canOptimizeRight = canOptimizeRight && bin.Left is BinaryExpression;
                 // TODO: this optimization should work for Unary Expression Too
                 // this actually produce errors becouse of string based Sql generation
                 if (canOptimizeRight)
                     if ((bool)bin.Right.Evaluate())
                         return Expression.Not(bin.Left);    // (X != TRUE) == not X 
                     else
                         return bin.Left;                    // (X != FALSE) == X
                 break;
         }
     return expression;
 }
 protected virtual Expression AnalyzeConstant(Expression expression, BuilderContext builderContext)
 {
     // we try to find a non-constant operand, and if we do, we won't change this expression
     foreach (var operand in expression.GetOperands())
     {
         if (!(operand is ConstantExpression))
             return expression;
     }
     if (expression.NodeType == ExpressionType.Parameter)
         return expression;
     if (expression.NodeType == (ExpressionType)SpecialExpressionType.Like)
         return expression;
     // SETuse
     // If the value of the first SpecialExpressionType change this 999 should change too
     if ((short)expression.NodeType > 999)
         return expression;
     // now, we just simply return a constant with new value
     try
     {
         var optimizedExpression = Expression.Constant(expression.Evaluate());
         // sometimes, optimizing an expression changes its type, and we just can't allow this.
         if (optimizedExpression.Type == expression.Type)
             return optimizedExpression;
     }
         // if we fail to evaluate the expression, then just return it
     catch (ArgumentException) 
     {
         return expression;
     }
     return expression;
 }