예제 #1
0
        /// <summary>
        /// Executes the actual query.  Called automatically when the query is evaluated
        /// </summary>
        public TResult Execute <TResult>(Expression expression)
        {
            LogLine("\r\n----------------- EXPRESSION --------------------\r\n");
            var localExpression = expression;

            LogLine(expression.ToString());

            // Reduce any parts of the expression that can be evaluated locally
            var simplifiedExpression = ExpressionSimplifier.Simplify(this.Queryable, localExpression);

            if (simplifiedExpression != localExpression)
            {
                LogLine("\r\n----------------- SIMPLIFIED EXPRESSION --------------------\r\n");
                localExpression = simplifiedExpression;
                LogLine(localExpression.ToString());
            }

            var pipeline = new MongoPipeline <TDocument>(_collection, AllowMongoDiskUse, LoggingDelegate);

            try
            {
                return(pipeline.Execute <TResult>(localExpression));
            }
            catch (MongoCommandException c)
            {
                if (c.Message.Contains("$in requires an array as a second argument, found: null"))
                {
                    throw new ArgumentNullException(".Contains on null Enumerable blew up.", c);
                }
                throw;
            }
        }
예제 #2
0
        /// <summary>
        /// Simplify an expression by evaluating immediately any sub-trees
        /// that exist entirely locally.  For now, that means anything that's
        /// not referenced from a Lambda parameter.  If nothing can be evaulated
        /// locally, then the original expression is returned.  Otherwise, a new
        /// expression is returned.
        /// </summary>
        /// <param name="rootQueryable">Queryable this expression is being executed against</param>
        /// <param name="expression">Expression to simplify</param>
        public static Expression Simplify(object rootQueryable, Expression expression)
        {
            // Simplification is accomplished in two passes.

            // Pass one, find ALL nodes that can be evaluated locally.
            var simplifier = new ExpressionSimplifier();

            simplifier.SaveIfSimplifiable(rootQueryable, expression);

            // Pass two, do a depth first search of the tree greedily evaluating
            // nodes whenever possible.
            return(simplifier.Visit(expression));
        }