internal void Compile(params object[] args) { if (this.fnQuery == null) { // first identify the query provider being used Expression body = this.query.Body; ConstantExpression root = RootQueryableFinder.Find(body) as ConstantExpression; if (root == null && args != null && args.Length > 0) { Expression replaced = ExpressionReplacer.ReplaceAll( body, this.query.Parameters.ToArray(), args.Select((a, i) => Expression.Constant(a, this.query.Parameters[i].Type)).ToArray() ); body = PartialEvaluator.Eval(replaced); root = RootQueryableFinder.Find(body) as ConstantExpression; } if (root == null) { throw new InvalidOperationException("Could not find query provider"); } // ask the query provider to compile the query by 'executing' the lambda expression IQueryProvider provider = ((IQueryable)root.Value).Provider; Delegate result = (Delegate)provider.Execute(this.query); System.Threading.Interlocked.CompareExchange(ref this.fnQuery, result, null); } }
private Expression BuildExecutionPlan(Expression expression) { var lambda = expression as LambdaExpression; if (lambda != null) { expression = lambda.Body; } var projection = Translate(expression); var rootQueryable = new RootQueryableFinder().Find(expression); var provider = Expression.Convert( Expression.Property(rootQueryable, typeof(IQueryable).GetProperty("Provider")), typeof(MongoQueryProvider)); return(new ExecutionBuilder().Build(projection, provider)); }
private Expression Translate(Expression expression) { var rootQueryable = new RootQueryableFinder().Find(expression); var elementType = ((IQueryable)((ConstantExpression)rootQueryable).Value).ElementType; expression = PartialEvaluator.Evaluate(expression, CanBeEvaluatedLocally); expression = new FieldBinder().Bind(expression, elementType); expression = new QueryBinder(this, expression).Bind(expression); expression = new AggregateRewriter().Rewrite(expression); expression = new RedundantFieldRemover().Remove(expression); expression = new RedundantSubqueryRemover().Remove(expression); expression = new OrderByRewriter().Rewrite(expression); expression = new RedundantFieldRemover().Remove(expression); expression = new RedundantSubqueryRemover().Remove(expression); return(expression); }