private Expression ParameterizeQuery(Expression expression, QueryProcessingContext context) { // Parameterize the expression by substituting any ConstantExpression // that is not a literal constant (such as a closure instance) with a ParameterExpression. return(new ConstantParameterizingExpressionVisitor(context.ParameterMapping).Visit(expression)); }
private Func <object[], object> CompileDelegate(Expression expression, QueryProcessingContext context) { var parameters = new ParameterExpression[context.ParameterMapping.Count + 1]; parameters[0] = context.ExecutionContextParameter; context.ParameterMapping.Values.CopyTo(parameters, 1); var parameterArray = Expression.Parameter(typeof(object[])); // Wrap the actual lambda in a static invocation. // This is faster than just compiling it and calling DynamicInvoke. return(Expression .Lambda <Func <object[], object> >( Expression.Convert( Expression.Invoke( Expression.Lambda(expression, parameters), parameters.Select((p, i) => Expression.Convert( Expression.ArrayIndex( parameterArray, Expression.Constant(i)), p.Type))), typeof(object)), parameterArray) .Compile()); }
private Expression InlineQuery(Expression expression, QueryProcessingContext context) { // Partially evaluate the expression. In addition to reducing evaluable nodes such // as `new DateTime(2000, 01, 01)` down to ConstantExpressions, this visitor also expands // IQueryable-producing expressions such as those found within calls to SelectMany // so that the resulting IQueryable's expression tree will be integrated into the // current expression tree. return(queryableInliningExpressionVisitorFactory.Create(context).Visit(expression)); }
public virtual IEnumerable <ExpressionVisitor> CreateExpressionVisitors(QueryProcessingContext context) { yield return(new QueryCompilingExpressionVisitor( translatabilityAnalyzingExpressionVisitor, queryTranslatingExpressionVisitorFactory, new MaterializerGeneratingExpressionVisitor( translatabilityAnalyzingExpressionVisitor, readValueExpressionFactoryProvider), context.ExecutionContextParameter)); }
public IEnumerable <ExpressionVisitor> CreateExpressionVisitors(QueryProcessingContext context) { yield return(new ConditionalComparisonOptimizingExpressionVisitor()); yield return(new SelectorPushdownExpressionVisitor()); yield return(new RedundantConversionStrippingExpressionVisitor()); yield return(new NullOrDefaultEqualityOptimizingExpressionVisitor()); yield return(new BooleanOptimizingExpressionVisitor()); }
public virtual IEnumerable <ExpressionVisitor> CreateExpressionVisitors(QueryProcessingContext context) { yield return(new KeyEqualityComposingExpressionVisitor(context.DescriptorSet)); yield return(new NavigationComposingExpressionVisitor(context.DescriptorSet.NavigationDescriptors)); yield return(new TableAliasComposingExpressionVisitor()); yield return(new QueryComposingExpressionVisitor( translatabilityAnalyzingExpressionVisitor, rewritingExpressionVisitorProvider.CreateExpressionVisitors(context), new SqlParameterRewritingExpressionVisitor(context.ParameterMapping.Values))); }
public virtual IEnumerable <ExpressionVisitor> CreateExpressionVisitors(QueryProcessingContext context) { yield return(new SqlServerObjectToStringRewritingExpressionVisitor()); yield return(new SqlServerStringToNumberAsciiRewritingExpressionVisitor()); yield return(new SqlServerCountRewritingExpressionVisitor()); yield return(new SqlServerMathMethodRewritingExpressionVisitor()); yield return(new SqlServerJsonMemberRewritingExpressionVisitor()); yield return(new SqlServerStringJoinRewritingExpressionVisitor(context)); }
private Expression ApplyVisitors(Expression expression, QueryProcessingContext context) { var composingExpressionVisitors = composingExpressionVisitorProvider .CreateExpressionVisitors(context) .ToArray(); var optimizingExpressionVisitors = optimizingExpressionVisitorProvider .CreateExpressionVisitors(context) .ToArray(); var compilingExpressionVisitors = compilingExpressionVisitorProvider .CreateExpressionVisitors(context) .ToArray(); // Apply all optimizing visitors before each composing visitor and then apply all // optimizing visitors one last time. foreach (var optimizingVisitor in optimizingExpressionVisitors) { expression = optimizingVisitor.Visit(expression); } foreach (var composingVisitor in composingExpressionVisitors) { expression = composingVisitor.Visit(expression); foreach (var optimizingVisitor in optimizingExpressionVisitors) { expression = optimizingVisitor.Visit(expression); } } // Transform the expression by rewriting all composed query expressions into // executable expressions that make database calls and perform result materialization. foreach (var compilingVisitor in compilingExpressionVisitors) { expression = compilingVisitor.Visit(expression); } return(expression); }
public virtual IEnumerable <ExpressionVisitor> CreateExpressionVisitors(QueryProcessingContext context) { /* * * Order-dependency notes: * * - ListContainsToEnumerableContainsRewritingExpressionVisitor * - has to run before EnumerableContainsRewritingExpressionVisitor * * - GroupingAggregationRewritingExpressionVisitor * - has to run before the QueryComposingExpressionVisitor recurses * * - SqlServerStringJoinRewritingExpressionVisitor * - has to run after the QueryComposingExpressionVisitor recurses * * Ideally none of these would be order-dependent beyond running before * or after the QueryComposingExpressionVisitor recurses. * */ yield return(new ListContainsToEnumerableContainsRewritingExpressionVisitor()); yield return(new EqualsMethodRewritingExpressionVisitor()); yield return(new KeyEqualityRewritingExpressionVisitor(context.DescriptorSet)); yield return(new GroupingAggregationRewritingExpressionVisitor(translatabilityAnalyzingExpressionVisitor)); yield return(new TypeBinaryExpressionRewritingExpressionVisitor()); yield return(new NullableMemberRewritingExpressionVisitor()); yield return(new DateTimeMemberRewritingExpressionVisitor()); yield return(new StringMemberRewritingExpressionVisitor()); yield return(new CollectionContainsRewritingExpressionVisitor()); yield return(new EnumerableContainsRewritingExpressionVisitor()); yield return(new EnumerableQueryEqualityRewritingExpressionVisitor()); yield return(new EnumHasFlagRewritingExpressionVisitor(typeMappingProvider)); }
public virtual IEnumerable <ExpressionVisitor> CreateExpressionVisitors(QueryProcessingContext context) { // 'Simple' replacement rewriters yield return(new ListContainsToEnumerableContainsRewritingExpressionVisitor()); yield return(new EqualsMethodRewritingExpressionVisitor()); // 'Core' rewriters yield return(new KeyEqualityRewritingExpressionVisitor(context.DescriptorSet)); yield return(new GroupingAggregationRewritingExpressionVisitor(translatabilityAnalyzingExpressionVisitor)); yield return(new TypeBinaryExpressionRewritingExpressionVisitor()); yield return(new NullableMemberRewritingExpressionVisitor()); yield return(new DateTimeMemberRewritingExpressionVisitor()); yield return(new StringMemberRewritingExpressionVisitor()); yield return(new CollectionContainsRewritingExpressionVisitor()); yield return(new EnumerableContainsRewritingExpressionVisitor()); yield return(new EnumerableQueryEqualityRewritingExpressionVisitor()); // SQL Server specific rewriters (should be pulled from the default provider at some point) yield return(new ObjectToStringRewritingExpressionVisitor()); yield return(new StringToNumberAsciiRewritingExpressionVisitor()); yield return(new SqlServerCountRewritingExpressionVisitor()); yield return(new SqlServerMathMethodRewritingExpressionVisitor()); yield return(new SqlServerJsonMemberRewritingExpressionVisitor()); }
private int ComputeHash(Expression expression, QueryProcessingContext context) { // Generate a hash code for the parameterized expression. // Because the expression is parameterized, the hash code will be identical // for expressions that are structurally equivalent apart from any closure instances. var comparer = ExpressionEqualityComparer.Instance; var hash = comparer.GetHashCode(expression); // Some parameters may have been eliminated during query inlining, // so we need to make sure all of our parameters' types are included // in the hash code to avoid errors related to mismatched closure types. unchecked { foreach (var parameter in context.ParameterMapping.Values) { hash = (hash * 16777619) ^ comparer.GetHashCode(parameter); } } return(hash); }
public QueryableInliningExpressionVisitor Create(QueryProcessingContext context) { return(new QueryableInliningExpressionVisitor(context.QueryProvider, context.ParameterMapping)); }