Example #1
0
        // Executes the expression tree that is passed to it.
        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.
            InnermostWhereFinder whereFinder      = new InnermostWhereFinder();
            MethodCallExpression whereExpression  = whereFinder.GetInnermostWhere(expression);
            LambdaExpression     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.
            LocationFinder lf        = new LocationFinder(lambdaExpression.Body);
            List <string>  locations = lf.Locations;

            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.
            Place[] places = WebServiceHelper.GetPlacesFromTerraServer(locations);

            // Copy the IEnumerable places to an IQueryable.
            IQueryable <Place> queryablePlaces = places.AsQueryable <Place>();

            // Copy the expression tree that was passed in, changing only the first
            // argument of the innermost MethodCallExpression.
            ExpressionTreeModifier treeCopier        = new ExpressionTreeModifier(queryablePlaces);
            Expression             newExpressionTree = treeCopier.CopyAndModify(expression);

            // This step creates an IQueryable that executes by replacing Queryable methods with Enumerable methods.
            if (IsEnumerable)
            {
                return(queryablePlaces.Provider.CreateQuery(newExpressionTree));
            }
            else
            {
                return(queryablePlaces.Provider.Execute(newExpressionTree));
            }
        }
        // 执行传递给它的表达式树。
        internal static object Execute(Expression expression, bool IsEnumerable)
        {
            // 表达式必须代表对数据源的查询。
            if (!IsQueryOverDataSource(expression))
            {
                throw new InvalidProgramException("No query over the data source was specified.");
            }

            // 找到对 Where() 的调用,并获取 lambda 表达式谓词。
            InnermostWhereFinder whereFinder      = new InnermostWhereFinder();
            MethodCallExpression whereExpression  = whereFinder.GetInnermostWhere(expression);
            LambdaExpression     lambdaExpression = (LambdaExpression)((UnaryExpression)(whereExpression.Arguments[1])).Operand;

            // 通过分部计算器发送 lambda 表达式。
            lambdaExpression = (LambdaExpression)Evaluator.PartialEval(lambdaExpression);

            // 获取要用于查询 Web 服务的位置名称。
            LocationFinder lf        = new LocationFinder(lambdaExpression.Body);
            List <string>  locations = lf.Locations;

            if (locations.Count == 0)
            {
                throw new InvalidQueryException("You must specify at least one place name in your query.");
            }

            // 调用 Web 服务并获取结果。
            Place[] places = WebServiceHelper.GetPlacesFromTerraServer(locations);

            // 将 IEnumerable 位置复制到 IQueryable。
            IQueryable <Place> queryablePlaces = places.AsQueryable <Place>();

            // 复制传入的表达式,只更改
            // 最内侧 MethodCallExpression 的第一个参数。
            ExpressionTreeModifier treeCopier        = new ExpressionTreeModifier(queryablePlaces);
            Expression             newExpressionTree = treeCopier.CopyAndModify(expression);

            // 此步骤将创建一个 IQueryable,它通过用可枚举方法替代可查询方法方法执行。
            if (IsEnumerable)
            {
                return(queryablePlaces.Provider.CreateQuery(newExpressionTree));
            }
            else
            {
                return(queryablePlaces.Provider.Execute(newExpressionTree));
            }
        }
Example #3
0
        // Выполняет дерево выражений, которое ему передается.
        internal static object Execute(Expression expression, bool IsEnumerable)
        {
            // Выражение должно представлять запрос к источнику данных.
            if (!IsQueryOverDataSource(expression))
            {
                throw new InvalidProgramException("No query over the data source was specified.");
            }

            // Найти вызов к Where() и получить предикат лямбда-выражения.
            InnermostWhereFinder whereFinder      = new InnermostWhereFinder();
            MethodCallExpression whereExpression  = whereFinder.GetInnermostWhere(expression);
            LambdaExpression     lambdaExpression = (LambdaExpression)((UnaryExpression)(whereExpression.Arguments[1])).Operand;

            // Переслать лямбда-выражение через частичный вычислитель.
            lambdaExpression = (LambdaExpression)Evaluator.PartialEval(lambdaExpression);

            // Получить имя (имена) вхождений для использования в запросе к веб-службе.
            LocationFinder lf        = new LocationFinder(lambdaExpression.Body);
            List <string>  locations = lf.Locations;

            if (locations.Count == 0)
            {
                throw new InvalidQueryException("You must specify at least one place name in your query.");
            }

            // Вызвать веб-службу и получить результаты.
            Place[] places = WebServiceHelper.GetPlacesFromTerraServer(locations);

            // Скопировать вхождения IEnumerable в IQueryable.
            IQueryable <Place> queryablePlaces = places.AsQueryable <Place>();

            // Скопировать переданное дерево выражений, меняя только первый
            // аргумент внутреннего MethodCallExpression.
            ExpressionTreeModifier treeCopier        = new ExpressionTreeModifier(queryablePlaces);
            Expression             newExpressionTree = treeCopier.CopyAndModify(expression);

            // На этом этапе создается IQueryable, который заменяет методы Queryable на методы Enumerable.
            if (IsEnumerable)
            {
                return(queryablePlaces.Provider.CreateQuery(newExpressionTree));
            }
            else
            {
                return(queryablePlaces.Provider.Execute(newExpressionTree));
            }
        }