public IExecutionPlan <T> Compile <T>(Expression expression) { // Define execution context as parameter ParameterExpression parameter = Expression.Parameter(typeof(IExecutionContext), "executionContext"); // Create new transformation context ITransformationContext context = new TransformationContext(parameter); TransformationStepRecorder recorder = new TransformationStepRecorder(); // Execute optimization expression = this.TransformExpression(expression, context, recorder); // Compile query Func <IExecutionContext, T> executable = this.CompileCore(expression, parameter) as Func <IExecutionContext, T>; // Compose result IExecutionPlanInfo info = new ExecutionPlanInfo(recorder.Steps); IExecutionPlan <T> plan = new ExecutionPlan <T>(executable, info); return(plan); }
private Expression TransformExpression( Expression expression, ITransformationContext context, TransformationStepRecorder recorder) { expression = this.PreprocessExpression(expression, context); if (context.IsFinished) { return(expression); } // Set up the rewriter chain IList <IExpressionRewriter> allRewriters = new IExpressionRewriter[] { new DatabaseParameterRewriter(context), new StoredProcedureParameterRewriter(context), } .Concat( this.GetRewriters(expression, context)) .Concat(new IExpressionRewriter[] { new TableScanRewriter(), new QueryableRewriter() }) .ToList(); // Initialize rewriters foreach (IDatabaseComponent databaseComponent in allRewriters) { databaseComponent.Initialize(this.database); } // Last chance to alter rewriters allRewriters = this.ReviewRewriters(allRewriters); // Record the initial state recorder.Record(new TransformationStep(expression)); // Execute rewriters foreach (IExpressionRewriter rewriter in allRewriters) { if (rewriter == null) { continue; } expression = rewriter.Rewrite(expression); recorder.Record(new TransformationStep(expression)); } expression = this.PostprocessExpression(expression, context); recorder.Record(new TransformationStep(expression)); // Reduce the expression while (expression.CanReduce) { expression = expression.Reduce(); recorder.Record(new TransformationStep(expression)); } return(expression); }