private CompiledQuery GetOrAdd( Expression query, QueryContext queryContext, IDatabase database, bool isAsync, Func <Expression, IDatabase, CompiledQuery> compiler) { query = new QueryAnnotatingExpressionVisitor() .Visit(query); var parameterizedQuery = ParameterExtractingExpressionVisitor .ExtractParameters(query, queryContext, new NullEvaluatableExpressionFilter()); var cacheKey = database.Model.GetHashCode().ToString() + isAsync + new ExpressionStringBuilder() .Build(query); CompiledQuery compiledQuery; lock (_compiledQueryLockObject) { if (!_memoryCache.TryGetValue(cacheKey, out compiledQuery)) { compiledQuery = compiler(parameterizedQuery, database); _memoryCache.Set(cacheKey, compiledQuery); } } return(compiledQuery); }
protected virtual Expression Preprocess([NotNull] Expression query, [NotNull] QueryContext queryContext) { Check.NotNull(query, nameof(query)); Check.NotNull(queryContext, nameof(queryContext)); query = new QueryAnnotatingExpressionVisitor().Visit(query); return(ParameterExtractingExpressionVisitor .ExtractParameters(query, queryContext, _evaluatableExpressionFilter)); }
public static IRelationalCommand CreateCommand(this IQueryable source) { var compilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var compiler = compilerField.GetValue(source.Provider); var queryContextFactoryField = compiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(compiler); var queryContext = queryContextFactory.Create(); var evalutableExpressionFilterField = compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evalutableExpressionFilter = (IEvaluatableExpressionFilter)evalutableExpressionFilterField.GetValue(null); var query = new QueryAnnotatingExpressionVisitor().Visit(source.Expression); var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(query, queryContext, evalutableExpressionFilter); var queryParserMethod = compiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var queryparser = (QueryParser)queryParserMethod.Invoke(null, new object[0]); var queryModel = queryparser.GetParsedQuery(newQuery); var databaseField = compiler.GetType().GetField("_database", BindingFlags.NonPublic | BindingFlags.Instance); var database = (IDatabase)databaseField.GetValue(compiler); var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); var queryModelVisitor = (RelationalQueryModelVisitor)queryCompilationContextFactory.Create(false).CreateQueryModelVisitor(); var createQueryExecutorMethod = queryModelVisitor.GetType().GetMethod("CreateQueryExecutor"); var createQueryExecutorMethodGeneric = createQueryExecutorMethod.MakeGenericMethod(source.ElementType); createQueryExecutorMethodGeneric.Invoke(queryModelVisitor, new[] { queryModel }); var queries = queryModelVisitor.Queries; var sqlQuery = queries.ToList()[0]; var command = sqlQuery.CreateGenerator().GenerateSql(queryContext.ParameterValues); return(command); }
/// <summary>Creates executor and get command.</summary> /// <returns>The new executor and get command.</returns> public virtual IRelationalCommand CreateExecutorAndGetCommand() { // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(Query.Provider); // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new object[0]); // REFLECTION: Query.Provider._queryCompiler._database var databaseField = queryCompiler.GetType().GetField("_database", BindingFlags.NonPublic | BindingFlags.Instance); var database = (IDatabase)databaseField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler._evaluatableExpressionFilter var evaluatableExpressionFilterField = queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evaluatableExpressionFilter = (IEvaluatableExpressionFilter)evaluatableExpressionFilterField.GetValue(null); // REFLECTION: Query.Provider._queryCompiler._queryContextFactory var queryContextFactoryField = queryCompiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.CreateQueryBuffer var createQueryBufferDelegateMethod = (typeof(QueryContextFactory)).GetMethod("CreateQueryBuffer", BindingFlags.NonPublic | BindingFlags.Instance); var createQueryBufferDelegate = (Func <IQueryBuffer>)createQueryBufferDelegateMethod.CreateDelegate(typeof(Func <IQueryBuffer>), queryContextFactory); // REFLECTION: Query.Provider._queryCompiler._queryContextFactory._connection var connectionField = queryContextFactory.GetType().GetField("_connection", BindingFlags.NonPublic | BindingFlags.Instance); var connection = (IRelationalConnection)connectionField.GetValue(queryContextFactory); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // CREATE connection QueryConnection = new CreateEntityRelationConnection(connection); // CREATE query context var queryContext = new RelationalQueryContext(createQueryBufferDelegate, QueryConnection); // CREATE a query visitor var queryVisitor = new QueryAnnotatingExpressionVisitor().Visit(Query.Expression); // CREATE new query from query visitor var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(queryVisitor, queryContext, evaluatableExpressionFilter); // PARSE new query var queryModel = createQueryParser.GetParsedQuery(newQuery); // CREATE query model visitor var queryModelVisitor = (RelationalQueryModelVisitor)queryCompilationContextFactory.Create(false).CreateQueryModelVisitor(); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Create(false).CreateQueryModelVisitor().CreateQueryExecutor() var createQueryExecutorMethod = queryModelVisitor.GetType().GetMethod("CreateQueryExecutor"); var createQueryExecutorMethodGeneric = createQueryExecutorMethod.MakeGenericMethod(Query.ElementType); var queryExecutor = createQueryExecutorMethodGeneric.Invoke(queryModelVisitor, new[] { queryModel }); // SET value QueryExecutor = queryExecutor; QueryContext = queryContext; // RETURN the IRealationCommand var sqlQuery = queryModelVisitor.Queries.First(); var relationalCommand = sqlQuery.CreateGenerator().GenerateSql(queryContext.ParameterValues); return(relationalCommand); }
internal static IEnumerable <T> MapReader <T>(this DbContext context, DbDataReader reader) where T : class { #if EF5 || EF6 return(((IObjectContextAdapter)context).ObjectContext.Translate <T>(reader)); #elif EFCORE var list = new List <T>(); var query = (IQueryable <T>)context.Set <T>(); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(query.Provider); // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new object[0]); // REFLECTION: Query.Provider._queryCompiler._database var databaseField = queryCompiler.GetType().GetField("_database", BindingFlags.NonPublic | BindingFlags.Instance); var database = (IDatabase)databaseField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler._evaluatableExpressionFilter var evaluatableExpressionFilterField = queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evaluatableExpressionFilter = (IEvaluatableExpressionFilter)evaluatableExpressionFilterField.GetValue(null); // REFLECTION: Query.Provider._queryCompiler._queryContextFactory var queryContextFactoryField = queryCompiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.CreateQueryBuffer var createQueryBufferDelegateMethod = (typeof(QueryContextFactory)).GetMethod("CreateQueryBuffer", BindingFlags.NonPublic | BindingFlags.Instance); var createQueryBufferDelegate = (Func <IQueryBuffer>)createQueryBufferDelegateMethod.CreateDelegate(typeof(Func <IQueryBuffer>), queryContextFactory); // REFLECTION: Query.Provider._queryCompiler._queryContextFactory._connection var connectionField = queryContextFactory.GetType().GetField("_connection", BindingFlags.NonPublic | BindingFlags.Instance); var connection = (IRelationalConnection)connectionField.GetValue(queryContextFactory); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // CREATE connection var queryConnection = new CreateEntityRelationConnection(connection); // CREATE query context var queryContext = new RelationalQueryContext(createQueryBufferDelegate, queryConnection); // CREATE a query visitor var queryVisitor = new QueryAnnotatingExpressionVisitor().Visit(query.Expression); // CREATE new query from query visitor var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(queryVisitor, queryContext, evaluatableExpressionFilter); // PARSE new query var queryModel = createQueryParser.GetParsedQuery(newQuery); // CREATE query model visitor var queryModelVisitor = (RelationalQueryModelVisitor)queryCompilationContextFactory.Create(false).CreateQueryModelVisitor(); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Create(false).CreateQueryModelVisitor().CreateQueryExecutor() var createQueryExecutorMethod = queryModelVisitor.GetType().GetMethod("CreateQueryExecutor"); var createQueryExecutorMethodGeneric = createQueryExecutorMethod.MakeGenericMethod(query.ElementType); var queryExecutor = (Func <QueryContext, IEnumerable <T> >)createQueryExecutorMethodGeneric.Invoke(queryModelVisitor, new[] { queryModel }); // CREATE a fake reader since EntityFramework close it queryConnection.OriginalDataReader = new CreateEntityDataReader(reader); var queryEnumerable = queryExecutor(queryContext); var enumerator = queryEnumerable.GetEnumerator(); while (enumerator.MoveNext()) { list.Add(enumerator.Current); } return(list); #endif }