Ejemplo n.º 1
0
        public void ClosureDiscovery()
        {
            var set1 = new List <object>().AsQueryable();

            var localVariable = new object();

            var query = from s1 in set1
                        where s1 == localVariable
                        select s1;

            var visitor = new ConstantParameterizingExpressionVisitor();

            visitor.Visit(query.Expression);

            Assert.AreEqual(1, visitor.Mapping.Count);
            Assert.IsTrue(visitor.Mapping.Keys.Single().GetType().GetTypeInfo().GetCustomAttribute <CompilerGeneratedAttribute>() != null);
        }
        object IQueryProvider.Execute(Expression expression)
        {
            try
            {
                var hashingVisitor = new HashingExpressionVisitor();
                expression = hashingVisitor.Visit(expression);

                var constantParameterizingVisitor = new ConstantParameterizingExpressionVisitor();
                expression = constantParameterizingVisitor.Visit(expression);

                var parameterMapping = constantParameterizingVisitor.Mapping;

                if (!QueryCache.TryGetValue(hashingVisitor.HashCode, out var compiled))
                {
                    expression = new QueryableExpandingExpressionVisitor(parameterMapping).Visit(expression);

                    expression = new PartialEvaluatingExpressionVisitor().Visit(expression);

                    var preCompositionVisitors = new[]
                    {
                        ExpressionVisitorProvider.OptimizingExpressionVisitors,
                        ExpressionVisitorProvider.MidOptimizationExpressionVisitors,
                        ExpressionVisitorProvider.OptimizingExpressionVisitors,
                    };

                    expression = preCompositionVisitors.SelectMany(vs => vs).Aggregate(expression, (e, v) => v.Visit(e));

                    expression = new QueryActivatingExpressionVisitor(this).Visit(expression);

                    expression = new QueryComposingExpressionVisitor(ExpressionVisitorProvider).Visit(expression);

                    var postCompositionVisitors = new[]
                    {
                        ExpressionVisitorProvider.OptimizingExpressionVisitors,
                    };

                    expression = postCompositionVisitors.SelectMany(vs => vs).Aggregate(expression, (e, v) => v.Visit(e));

                    var queryProviderParameter = Expression.Parameter(typeof(ImpatientQueryProvider), "queryProvider");

                    expression = new QueryCompilingExpressionVisitor(ExpressionVisitorProvider, queryProviderParameter).Visit(expression);

                    var parameters = new ParameterExpression[parameterMapping.Count + 1];

                    parameters[0] = queryProviderParameter;

                    parameterMapping.Values.CopyTo(parameters, 1);

                    compiled = Expression.Lambda(expression, parameters).Compile();

                    QueryCache.Add(hashingVisitor.HashCode, compiled);
                }

                var arguments = new object[parameterMapping.Count + 1];

                arguments[0] = this;

                parameterMapping.Keys.CopyTo(arguments, 1);

                return(compiled.DynamicInvoke(arguments));
            }
            catch (TargetInvocationException targetInvocationException)
            {
                throw targetInvocationException.InnerException;
            }
        }