/// <summary> /// Executes the expression tree that is passed to it. /// </summary> /// <param name="expression">Expression Tree</param> /// <param name="isEnumerable"></param> /// <returns></returns> internal static object Execute(Expression expression, bool isEnumerable) { // The expression must represent a query over the data source. if (!IsQueryOverDataSource(expression)) { throw new InvalidProgramException("No query over the data source was specified."); } // Find the call to Where() and get the lambda expression predicate. var whereFinder = new InnermostWhereFinder(); var whereExpression = whereFinder.GetInnermostWhere(expression); var lambdaExpression = (LambdaExpression)((UnaryExpression)(whereExpression.Arguments[1])).Operand; // Send the lambda expression through the partial evaluator. lambdaExpression = (LambdaExpression)Evaluator.PartialEval(lambdaExpression); // Get the place name(s) to query the Web service with. var lf = new TrackFinder(lambdaExpression.Body); var locations = lf.TrackNames; if (locations.Count == 0) { throw new InvalidQueryException("You must specify at least one place name in your query."); } // Call the Web service and get the results. Track[] places = WebServiceHelper.GetTracks(locations); // Copy the IEnumerable places to an IQueryable. IQueryable <Track> queryablePlaces = places.AsQueryable(); // Copy the expression tree that was passed in, changing only the first // argument of the innermost MethodCallExpression. var treeCopier = new ExpressionTreeModifier(queryablePlaces); var newExpressionTree = treeCopier.Visit(expression); // This step creates an IQueryable that executes by replacing Queryable methods with Enumerable methods. if (isEnumerable) { return(queryablePlaces.Provider.CreateQuery(newExpressionTree)); } return(queryablePlaces.Provider.Execute(newExpressionTree)); }
static void Main(string[] args) { ExpressionTreeModifier modifier = new ExpressionTreeModifier(); Expression <Func <int, int, int, int> > expr = (a, b, c) => a + b * (c + 1); Console.WriteLine(expr); Console.WriteLine(expr.Compile()(1, 2, 3)); Expression <Func <int, int, int, int> > expr1 = modifier.VisitAndConvert(expr, ""); Console.WriteLine(expr1); Console.WriteLine(expr1.Compile()(1, 2, 3)); Dictionary <string, object> constants = new Dictionary <string, object> { { "a", 1 }, { "d", 2 }, { "c", 3 } }; LambdaExpression expr2 = (LambdaExpression)modifier.Modify(expr, constants); Console.WriteLine(expr2); Console.WriteLine(expr2.Compile()(1, 2, 3)); Console.ReadKey(); }