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); } }
/// <summary> /// Convert the query expression into an execution plan /// </summary> /// <param name="expression"></param> /// <returns></returns> protected virtual Expression GetExecutionPlan(Expression expression) { // strip off lambda for now LambdaExpression lambda = expression as LambdaExpression; if (lambda != null) { expression = lambda.Body; } // translate query into client and server parts ProjectionExpression projection = Translate(expression); Expression rootQueryable = RootQueryableFinder.Find(expression); Expression provider = Expression.Convert( Expression.Property(rootQueryable, typeof(IQueryable).GetProperty("Provider")), typeof(DbQueryProvider) ); return(policy.BuildExecutionPlan(projection, provider)); }