/// <summary>
        /// Optimizes the filter; but does not try to combine nested filter (etc.)
        /// </summary>
        QueryNode OptimizeFilter(Filter filter)
        {
            QueryNode target = Visit(filter.Target);

            List <LambdaExpression>        newConditions = new List <LambdaExpression>();
            OptimizeQueryExpressionVisitor optimizer     = new OptimizeQueryExpressionVisitor();

            foreach (LambdaExpression expr in filter.Conditions)
            {
                Expression optimizedExpr = optimizer.Visit(expr.Body);
                if (optimizedExpr.NodeType == ExpressionType.Constant && optimizedExpr.Type == typeof(bool))
                {
                    bool val = (bool)((ConstantExpression)optimizedExpr).Value;
                    if (val)
                    {
                        continue;
                    }
                }
                newConditions.Add(Expression.Lambda(optimizedExpr, expr.Parameters));
            }
            if (newConditions.Count == 0)
            {
                return(target);
            }
            else
            {
                return(new Filter(target, newConditions.ToArray()));
            }
        }
Пример #2
0
        public override object Execute(Expression inputExpression)
        {
            Stopwatch  watch = Stopwatch.StartNew();
            Expression partiallyEvaluatedExpression = PartialEvaluator.Eval(inputExpression, CanBeEvaluatedStatically);

            QueryExecutionOptions options    = new QueryExecutionOptions();
            Expression            expression = new ConvertToQueryAstVisitor(options).Visit(partiallyEvaluatedExpression);

            // options have been initialized by ConvertToQueryAstVisitor, start logging:
            if (options.HasLoggers)
            {
                options.WriteLogLine("Input expression: " + inputExpression);
                options.WriteLogLine("Partially evaluated expression: " + partiallyEvaluatedExpression);
                options.WriteLogLine("Converted to Query AST: " + expression);
            }

            expression = new OptimizeQueryExpressionVisitor().Visit(expression);
            if (options.HasLoggers)
            {
                options.WriteLogLine("Optimized Query AST: " + expression);
                options.WriteLogLine("Query preparation time: " + watch.Elapsed);
            }

            object result;
            // If the whole query was converted, execute it:
            QueryNode query = expression as QueryNode;

            if (query != null)
            {
                result = query.Execute(this, options);
            }
            else
            {
                // Query not converted completely: we have to use a LINQ-To-Objects / LINQ-To-Profiler mix
                expression = new ExecuteAllQueriesVisitor(this, options).Visit(expression);
                if (expression.Type.IsValueType)
                {
                    expression = Expression.Convert(expression, typeof(object));
                }
                var lambdaExpression = Expression.Lambda <Func <object> >(expression);
                result = lambdaExpression.Compile()();
            }
            watch.Stop();
            options.WriteLogLine("Total query execution time: " + watch.Elapsed);
            return(result);
        }
		/// <summary>
		/// Optimizes the filter; but does not try to combine nested filter (etc.)
		/// </summary>
		QueryNode OptimizeFilter(Filter filter)
		{
			QueryNode target = Visit(filter.Target);
			
			List<LambdaExpression> newConditions = new List<LambdaExpression>();
			OptimizeQueryExpressionVisitor optimizer = new OptimizeQueryExpressionVisitor();
			foreach (LambdaExpression expr in filter.Conditions) {
				Expression optimizedExpr = optimizer.Visit(expr.Body);
				if (optimizedExpr.NodeType == ExpressionType.Constant && optimizedExpr.Type == typeof(bool)) {
					bool val = (bool)((ConstantExpression)optimizedExpr).Value;
					if (val)
						continue;
				}
				newConditions.Add(Expression.Lambda(optimizedExpr, expr.Parameters));
			}
			if (newConditions.Count == 0)
				return target;
			else
				return new Filter(target, newConditions.ToArray());
		}
		public override object Execute(Expression inputExpression)
		{
			Stopwatch watch = Stopwatch.StartNew();
			Expression partiallyEvaluatedExpression = PartialEvaluator.Eval(inputExpression, CanBeEvaluatedStatically);
			
			QueryExecutionOptions options = new QueryExecutionOptions();
			Expression expression = new ConvertToQueryAstVisitor(options).Visit(partiallyEvaluatedExpression);
			// options have been initialized by ConvertToQueryAstVisitor, start logging:
			if (options.HasLoggers) {
				options.WriteLogLine("Input expression: " + inputExpression);
				options.WriteLogLine("Partially evaluated expression: " + partiallyEvaluatedExpression);
				options.WriteLogLine("Converted to Query AST: " + expression);
			}
			
			expression = new OptimizeQueryExpressionVisitor().Visit(expression);
			if (options.HasLoggers) {
				options.WriteLogLine("Optimized Query AST: " + expression);
				options.WriteLogLine("Query preparation time: " + watch.Elapsed);
			}
			
			object result;
			// If the whole query was converted, execute it:
			QueryNode query = expression as QueryNode;
			if (query != null) {
				result = query.Execute(this, options);
			} else {
				// Query not converted completely: we have to use a LINQ-To-Objects / LINQ-To-Profiler mix
				expression = new ExecuteAllQueriesVisitor(this, options).Visit(expression);
				if (expression.Type.IsValueType) {
					expression = Expression.Convert(expression, typeof(object));
				}
				var lambdaExpression = Expression.Lambda<Func<object>>(expression);
				result = lambdaExpression.Compile()();
			}
			watch.Stop();
			options.WriteLogLine("Total query execution time: " + watch.Elapsed);
			return result;
		}