/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public QueryCompiler( [NotNull] IQueryContextFactory queryContextFactory, [NotNull] ICompiledQueryCache compiledQueryCache, [NotNull] ICompiledQueryCacheKeyGenerator compiledQueryCacheKeyGenerator, [NotNull] IDatabase database, [NotNull] IDiagnosticsLogger <DbLoggerCategory.Query> logger, [NotNull] ICurrentDbContext currentContext, [NotNull] IQueryModelGenerator queryModelGenerator, [NotNull] IEvaluatableExpressionFilter evaluatableExpressionFilter, [NotNull] IModel model) { Check.NotNull(queryContextFactory, nameof(queryContextFactory)); Check.NotNull(compiledQueryCache, nameof(compiledQueryCache)); Check.NotNull(compiledQueryCacheKeyGenerator, nameof(compiledQueryCacheKeyGenerator)); Check.NotNull(database, nameof(database)); Check.NotNull(logger, nameof(logger)); Check.NotNull(currentContext, nameof(currentContext)); Check.NotNull(evaluatableExpressionFilter, nameof(evaluatableExpressionFilter)); Check.NotNull(model, nameof(model)); _queryContextFactory = queryContextFactory; _compiledQueryCache = compiledQueryCache; _compiledQueryCacheKeyGenerator = compiledQueryCacheKeyGenerator; _database = database; _logger = logger; _contextType = currentContext.Context.GetType(); _evaluatableExpressionFilter = evaluatableExpressionFilter; _model = model; }
private static Func <QueryContext, TResult> CompileAsyncQueryCore <TResult>( Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database) { var queryModel = queryModelGenerator.ParseQuery(query); var resultItemType = (queryModel.GetOutputDataInfo() as StreamedSequenceInfo)?.ResultItemType ?? typeof(TResult).TryGetSequenceType(); try { return((Func <QueryContext, TResult>)CompileAsyncQueryMethod .MakeGenericMethod(resultItemType) .Invoke(database, new object[] { queryModel })); } catch (TargetInvocationException e) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); throw; } }
public CustomQueryCompiler(IQueryContextFactory queryContextFactory, ICompiledQueryCache compiledQueryCache, ICompiledQueryCacheKeyGenerator compiledQueryCacheKeyGenerator , IDatabase database, IDiagnosticsLogger <DbLoggerCategory.Query> logger, ICurrentDbContext currentContext, IQueryModelGenerator queryModelGenerator, IEvaluatableExpressionFilter evaluatableExpressionFilter) : base(queryContextFactory, compiledQueryCache, compiledQueryCacheKeyGenerator, database, logger, currentContext, queryModelGenerator) { Check.NotNull(queryContextFactory, nameof(queryContextFactory)); Check.NotNull(compiledQueryCache, nameof(compiledQueryCache)); Check.NotNull(compiledQueryCacheKeyGenerator, nameof(compiledQueryCacheKeyGenerator)); Check.NotNull(database, nameof(database)); Check.NotNull(logger, nameof(logger)); Check.NotNull(currentContext, nameof(currentContext)); Check.NotNull(evaluatableExpressionFilter, nameof(evaluatableExpressionFilter)); _queryContextFactory = queryContextFactory; _compiledQueryCache = compiledQueryCache; _compiledQueryCacheKeyGenerator = compiledQueryCacheKeyGenerator; _database = database; _logger = logger; _contextType = currentContext.Context.GetType(); _queryModelGenerator = queryModelGenerator; _logFormatter = (queryKey, ex) => $"Cache hit for query [0x{queryKey}] with: {ex?.Message ?? "no error"}"; _cacheableOptions = currentContext.Context .GetService <IDbContextServices>() .ContextOptions .FindExtension <CacheableOptionsExtension>(); _cacheProvider = currentContext.Context.GetService <ICacheProvider>(); }
public CustomQueryCompiler( IQueryContextFactory queryContextFactory, ICompiledQueryCache compiledQueryCache, ICompiledQueryCacheKeyGenerator compiledQueryCacheKeyGenerator, IDatabase database, IDiagnosticsLogger <DbLoggerCategory.Query> logger, ICurrentDbContext currentContext, IQueryModelGenerator queryModelGenerator, IEvaluatableExpressionFilter evaluableExpressionFilter) : base(queryContextFactory, compiledQueryCache, compiledQueryCacheKeyGenerator, database, logger, currentContext, queryModelGenerator) { Check.NotNull(queryContextFactory, nameof(queryContextFactory)); Check.NotNull(compiledQueryCache, nameof(compiledQueryCache)); Check.NotNull(compiledQueryCacheKeyGenerator, nameof(compiledQueryCacheKeyGenerator)); Check.NotNull(database, nameof(database)); Check.NotNull(logger, nameof(logger)); Check.NotNull(currentContext, nameof(currentContext)); Check.NotNull(evaluableExpressionFilter, nameof(evaluableExpressionFilter)); _queryModelGenerator = queryModelGenerator; _cacheProvider = currentContext.Context.GetService <ICacheProvider>(); _xxHash = xxHashFactory.Instance.Create(new xxHashConfig() { HashSizeInBits = 64 }); }
public ScopeFilterModelExpressionApplyingExpressionVisitor(QueryCompilationContext queryCompilationContext, IQueryModelGenerator queryModelGenerator, EntityQueryModelVisitor entityQueryModelVisitor, IScopeFilterStore store) : base(queryCompilationContext, queryModelGenerator, entityQueryModelVisitor) { _queryCompilationContext = queryCompilationContext; _queryModelGenerator = queryModelGenerator; _store = store; }
private static Func <QueryContext, TResult> CompileQueryCore <TResult>( Expression query, IModel model, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger <DbLoggerCategory.Query> logger, Type contextType) { query = ExpandNavigations(query, model); var queryModel = queryModelGenerator.ParseQuery(query); // this is temporary, until relinq is removed var tirev = new TransparentIdentifierRemovingVisitor(); queryModel.TransformExpressions(tirev.Visit); var atasev = new AnonymousObjectAccessSimplifyingVisitor(); queryModel.TransformExpressions(atasev.Visit); var resultItemType = (queryModel.GetOutputDataInfo() as StreamedSequenceInfo)?.ResultItemType ?? typeof(TResult); if (resultItemType == typeof(TResult)) { var compiledQuery = database.CompileQuery <TResult>(queryModel); return(qc => { try { return compiledQuery(qc).First(); } catch (Exception exception) { logger.QueryIterationFailed(contextType, exception); throw; } }); } try { return((Func <QueryContext, TResult>)CompileQueryMethod .MakeGenericMethod(resultItemType) .Invoke(database, new object[] { queryModel })); } catch (TargetInvocationException e) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); throw; } }
private static Func <QueryContext, IAsyncEnumerable <TResult> > CompileAsyncQueryCore <TResult>( Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database) { var queryModel = queryModelGenerator.ParseQuery(query); return(database.CompileAsyncQuery <TResult>(queryModel)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public FilterApplyingExpressionVisitor( [NotNull] QueryCompilationContext queryCompilationContext, [NotNull] IQueryModelGenerator queryModelGenerator) { Check.NotNull(queryCompilationContext, nameof(queryCompilationContext)); Check.NotNull(queryModelGenerator, nameof(queryModelGenerator)); _queryCompilationContext = queryCompilationContext; _queryModelGenerator = queryModelGenerator; }
public ExpressionVisitor( QueryCompilationContext compilationContext, IQueryModelGenerator generator, EntityQueryModelVisitor visitor) : base(compilationContext, generator, visitor) { this.compilationContext = compilationContext; this.generator = generator; instanceFilters = filters.Value; parameters = (IParameterValues)parameterField.GetValue(this); }
public static string ToSql <TEntity>(this IQueryable <TEntity> query, DbContext dbCtx) { IQueryModelGenerator modelGenerator = dbCtx.GetService <IQueryModelGenerator>(); QueryModel queryModel = modelGenerator.ParseQuery(query.Expression); DatabaseDependencies databaseDependencies = dbCtx.GetService <DatabaseDependencies>(); QueryCompilationContext queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false); RelationalQueryModelVisitor modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); modelVisitor.CreateQueryExecutor <TEntity>(queryModel); var sql = modelVisitor.Queries.First().ToString(); return(sql); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public ModelExpressionApplyingExpressionVisitor( [NotNull] QueryCompilationContext queryCompilationContext, [NotNull] IQueryModelGenerator queryModelGenerator, [NotNull] EntityQueryModelVisitor entityQueryModelVisitor) { Check.NotNull(queryCompilationContext, nameof(queryCompilationContext)); Check.NotNull(queryModelGenerator, nameof(queryModelGenerator)); Check.NotNull(entityQueryModelVisitor, nameof(entityQueryModelVisitor)); _queryCompilationContext = queryCompilationContext; _queryModelGenerator = queryModelGenerator; _entityQueryModelVisitor = entityQueryModelVisitor; }
/// <summary> /// Clones this dependency parameter object with one service replaced. /// </summary> /// <param name="queryModelGenerator"> A replacement for the current dependency of this type. </param> /// <returns> A new parameter object with the given service replaced. </returns> public EntityQueryModelVisitorDependencies With([NotNull] IQueryModelGenerator queryModelGenerator) => new EntityQueryModelVisitorDependencies( QueryOptimizer, QuerySourceTracingExpressionVisitorFactory, EntityResultFindingExpressionVisitorFactory, EagerLoadingExpressionVisitorFactory, TaskBlockingExpressionVisitor, MemberAccessBindingExpressionVisitorFactory, ProjectionExpressionVisitorFactory, EntityQueryableExpressionVisitorFactory, QueryAnnotationExtractor, ResultOperatorHandler, EntityMaterializerSource, ExpressionPrinter, queryModelGenerator);
/// <summary> /// <para> /// Creates the service dependencies parameter object for a <see cref="EntityQueryModelVisitorFactory" />. /// </para> /// <para> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </para> /// <para> /// Do not call this constructor directly from either provider or application code as it may change /// as new dependencies are added. Instead, use this type in your constructor so that an instance /// will be created and injected automatically by the dependency injection container. To create /// an instance with some dependent services replaced, first resolve the object from the dependency /// injection container, then replace selected services using the 'With...' methods. Do not call /// the constructor at any point in this process. /// </para> /// </summary> /// <param name="queryOptimizer"> The <see cref="IQueryOptimizer" /> to be used when processing the query. </param> /// <param name="navigationRewritingExpressionVisitorFactory"> /// The <see cref="INavigationRewritingExpressionVisitorFactory" /> to be used when /// processing the query. /// </param> /// <param name="querySourceTracingExpressionVisitorFactory"> /// The <see cref="IQuerySourceTracingExpressionVisitorFactory" /> to be used when /// processing the query. /// </param> /// <param name="entityResultFindingExpressionVisitorFactory"> /// The <see cref="IEntityResultFindingExpressionVisitorFactory" /> to be used when /// processing the query. /// </param> /// <param name="eagerLoadingExpressionVisitorFactory"> /// The <see cref="IEagerLoadingExpressionVisitorFactory" /> to be used when /// processing the query. /// </param> /// <param name="taskBlockingExpressionVisitor"> The <see cref="ITaskBlockingExpressionVisitor" /> to be used when processing the query. </param> /// <param name="memberAccessBindingExpressionVisitorFactory"> /// The <see cref="IMemberAccessBindingExpressionVisitorFactory" /> to be used when /// processing the query. /// </param> /// <param name="projectionExpressionVisitorFactory"> /// The <see cref="IProjectionExpressionVisitorFactory" /> to be used when processing the /// query. /// </param> /// <param name="entityQueryableExpressionVisitorFactory"> /// The <see cref="IEntityQueryableExpressionVisitorFactory" /> to be used when /// processing the query. /// </param> /// <param name="queryAnnotationExtractor"> The <see cref="IQueryAnnotationExtractor" /> to be used when processing the query. </param> /// <param name="resultOperatorHandler"> The <see cref="IResultOperatorHandler" /> to be used when processing the query. </param> /// <param name="entityMaterializerSource"> The <see cref="IEntityMaterializerSource" /> to be used when processing the query. </param> /// <param name="expressionPrinter"> The <see cref="IExpressionPrinter" /> to be used when processing the query. </param> /// <param name="queryModelGenerator"> The <see cref="IQueryModelGenerator" /> to be used when processing the query. </param> public EntityQueryModelVisitorDependencies( [NotNull] IQueryOptimizer queryOptimizer, [NotNull] INavigationRewritingExpressionVisitorFactory navigationRewritingExpressionVisitorFactory, [NotNull] IQuerySourceTracingExpressionVisitorFactory querySourceTracingExpressionVisitorFactory, [NotNull] IEntityResultFindingExpressionVisitorFactory entityResultFindingExpressionVisitorFactory, [NotNull] IEagerLoadingExpressionVisitorFactory eagerLoadingExpressionVisitorFactory, [NotNull] ITaskBlockingExpressionVisitor taskBlockingExpressionVisitor, [NotNull] IMemberAccessBindingExpressionVisitorFactory memberAccessBindingExpressionVisitorFactory, [NotNull] IProjectionExpressionVisitorFactory projectionExpressionVisitorFactory, [NotNull] IEntityQueryableExpressionVisitorFactory entityQueryableExpressionVisitorFactory, [NotNull] IQueryAnnotationExtractor queryAnnotationExtractor, [NotNull] IResultOperatorHandler resultOperatorHandler, [NotNull] IEntityMaterializerSource entityMaterializerSource, [NotNull] IExpressionPrinter expressionPrinter, [NotNull] IQueryModelGenerator queryModelGenerator) { Check.NotNull(queryOptimizer, nameof(queryOptimizer)); Check.NotNull(navigationRewritingExpressionVisitorFactory, nameof(navigationRewritingExpressionVisitorFactory)); Check.NotNull(querySourceTracingExpressionVisitorFactory, nameof(querySourceTracingExpressionVisitorFactory)); Check.NotNull(entityResultFindingExpressionVisitorFactory, nameof(entityResultFindingExpressionVisitorFactory)); Check.NotNull(eagerLoadingExpressionVisitorFactory, nameof(eagerLoadingExpressionVisitorFactory)); Check.NotNull(taskBlockingExpressionVisitor, nameof(taskBlockingExpressionVisitor)); Check.NotNull(memberAccessBindingExpressionVisitorFactory, nameof(memberAccessBindingExpressionVisitorFactory)); Check.NotNull(projectionExpressionVisitorFactory, nameof(projectionExpressionVisitorFactory)); Check.NotNull(entityQueryableExpressionVisitorFactory, nameof(entityQueryableExpressionVisitorFactory)); Check.NotNull(queryAnnotationExtractor, nameof(queryAnnotationExtractor)); Check.NotNull(resultOperatorHandler, nameof(resultOperatorHandler)); Check.NotNull(entityMaterializerSource, nameof(entityMaterializerSource)); Check.NotNull(expressionPrinter, nameof(expressionPrinter)); Check.NotNull(queryModelGenerator, nameof(queryModelGenerator)); QueryOptimizer = queryOptimizer; NavigationRewritingExpressionVisitorFactory = navigationRewritingExpressionVisitorFactory; QuerySourceTracingExpressionVisitorFactory = querySourceTracingExpressionVisitorFactory; EntityResultFindingExpressionVisitorFactory = entityResultFindingExpressionVisitorFactory; EagerLoadingExpressionVisitorFactory = eagerLoadingExpressionVisitorFactory; TaskBlockingExpressionVisitor = taskBlockingExpressionVisitor; MemberAccessBindingExpressionVisitorFactory = memberAccessBindingExpressionVisitorFactory; ProjectionExpressionVisitorFactory = projectionExpressionVisitorFactory; EntityQueryableExpressionVisitorFactory = entityQueryableExpressionVisitorFactory; QueryAnnotationExtractor = queryAnnotationExtractor; ResultOperatorHandler = resultOperatorHandler; EntityMaterializerSource = entityMaterializerSource; ExpressionPrinter = expressionPrinter; QueryModelGenerator = queryModelGenerator; }
public CustomQueryCompiler(IQueryContextFactory queryContextFactory, ICompiledQueryCache compiledQueryCache, ICompiledQueryCacheKeyGenerator compiledQueryCacheKeyGenerator, IDatabase database, IDiagnosticsLogger <DbLoggerCategory.Query> logger, ICurrentDbContext currentContext, IQueryModelGenerator queryModelGenerator) : base(queryContextFactory, compiledQueryCache, compiledQueryCacheKeyGenerator, database, logger, currentContext, queryModelGenerator) { _logger = logger.Logger; }
private static Func <QueryContext, TResult> CompileQueryCore <TResult>( Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger <DbLoggerCategory.Query> logger, Type contextType) { var queryModel = queryModelGenerator.ParseQuery(query); var resultItemType = (queryModel.GetOutputDataInfo() as StreamedSequenceInfo)?.ResultItemType ?? typeof(TResult); if (resultItemType == typeof(TResult)) { var compiledQuery = database.CompileQuery <TResult>(queryModel); return(qc => { try { return compiledQuery(qc).First(); } catch (Exception exception) { logger.QueryIterationFailed(contextType, exception); throw; } }); } try { return((Func <QueryContext, TResult>)CompileQueryMethod .MakeGenericMethod(resultItemType) .Invoke(database, new object[] { queryModel })); } catch (TargetInvocationException e) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); throw; } }
public static string ToSql <TEntity>(this IQueryable <TEntity> queryable) where TEntity : class { if (!(queryable is EntityQueryable <TEntity>) && !(queryable is InternalDbSet <TEntity>)) { throw new ArgumentException(); } IQueryCompiler queryCompiler = (IQueryCompiler)_queryCompilerField.GetValue(queryable.Provider); IQueryModelGenerator queryModelGenerator = (IQueryModelGenerator)_queryModelGeneratorField.GetValue(queryCompiler); QueryModel queryModel = queryModelGenerator.ParseQuery(queryable.Expression); object database = _databaseField.GetValue(queryCompiler); IQueryCompilationContextFactory queryCompilationContextFactory = ((DatabaseDependencies)_dependenciesProperty.GetValue(database)).QueryCompilationContextFactory; QueryCompilationContext queryCompilationContext = queryCompilationContextFactory.Create(false); RelationalQueryModelVisitor modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); modelVisitor.CreateQueryExecutor <TEntity>(queryModel); return(modelVisitor.Queries.Join(Environment.NewLine + Environment.NewLine)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public ModelExpressionApplyingExpressionVisitor( [NotNull] QueryCompilationContext queryCompilationContext, [NotNull] IQueryModelGenerator queryModelGenerator, [NotNull] EntityQueryModelVisitor entityQueryModelVisitor) { Check.NotNull(queryCompilationContext, nameof(queryCompilationContext)); Check.NotNull(queryModelGenerator, nameof(queryModelGenerator)); Check.NotNull(entityQueryModelVisitor, nameof(entityQueryModelVisitor)); _queryCompilationContext = queryCompilationContext; _queryModelGenerator = queryModelGenerator; _entityQueryModelVisitor = entityQueryModelVisitor; _parameterExtractingExpressionVisitor = new ParameterExtractingExpressionVisitor( ((QueryModelGenerator)queryModelGenerator).EvaluatableExpressionFilter, _parameters, _queryCompilationContext.ContextType, _queryCompilationContext.Logger, parameterize: false, generateContextAccessors: true); }
private static string getExpressionKeyHash( IQueryCompiler queryCompiler, IQueryModelGenerator queryModelGenerator, IEFCacheKeyHashProvider cacheKeyHashProvider, Expression expression) { var queryContextFactory = (IQueryContextFactory)_queryContextFactoryField.GetValue(queryCompiler); var queryContext = queryContextFactory.Create(); var logger = (IDiagnosticsLogger <DbLoggerCategory.Query>)_loggerField.GetValue(queryCompiler); expression = queryModelGenerator.ExtractParameters(logger, expression, queryContext); var expressionKey = $"{ExpressionEqualityComparer.Instance.GetHashCode(expression)};"; var parameterValues = queryContext.ParameterValues; if (parameterValues.Any()) { expressionKey = parameterValues.Aggregate(expressionKey, (current, item) => current + $"{item.Key}={item.Value?.GetHashCode()};"); } return(cacheKeyHashProvider.ComputeHash(expressionKey)); }
private static Func <QueryContext, TResult> CompileAsyncQueryCore <TResult>( Expression query, IModel model, IQueryModelGenerator queryModelGenerator, IDatabase database) { query = ExpandNavigations(query, model); var queryModel = queryModelGenerator.ParseQuery(query); // this is temporary, until relinq is removed var tirev = new TransparentIdentifierRemovingVisitor(); queryModel.TransformExpressions(tirev.Visit); var atasev = new AnonymousObjectAccessSimplifyingVisitor(); queryModel.TransformExpressions(atasev.Visit); var resultItemType = (queryModel.GetOutputDataInfo() as StreamedSequenceInfo)?.ResultItemType ?? typeof(TResult).TryGetSequenceType(); try { return((Func <QueryContext, TResult>)CompileAsyncQueryMethod .MakeGenericMethod(resultItemType) .Invoke(database, new object[] { queryModel })); } catch (TargetInvocationException e) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); throw; } }
private static Func <QueryContext, TResult> CompileQueryCore <TResult>( Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger <DbLoggerCategory.Query> logger, Type contextType, bool getRealResult = false) { var queryModel = queryModelGenerator.ParseQuery(query); var resultItemType = (queryModel.GetOutputDataInfo() as StreamedSequenceInfo)?.ResultItemType ?? typeof(TResult); if (resultItemType == typeof(TResult)) { var compiledQuery = database.CompileQuery <TResult>(queryModel); return(qc => { try { return compiledQuery(qc).First(); } catch (Exception exception) { logger.QueryIterationFailed(contextType, exception); throw; } }); } try { // differs from base implmentation to return DB query result var compileFunction = (Func <QueryContext, TResult>)CompileQueryMethod .MakeGenericMethod(resultItemType) .Invoke(database, new object[] { queryModel }); return(qc => { try { // calling ToList to materialize result var genericToListMethod = ToListMethod.MakeGenericMethod(new Type[] { resultItemType }); var result = genericToListMethod.Invoke(compileFunction(qc), new object[] { compileFunction(qc) }); return (TResult)result; } catch (Exception exception) { logger.QueryIterationFailed(contextType, exception); throw; } }); } catch (TargetInvocationException e) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); throw; } }