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); }
public static IRelationalCommand CreateCommand(this IQueryable source, out RelationalQueryContext queryContext) { var compilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var compiler = compilerField.GetValue(source.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderField = compiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); var nodeTypeProvider = nodeTypeProviderField.GetValue(compiler); var queryContextFactoryField = compiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(compiler); queryContext = (RelationalQueryContext)queryContextFactory.Create(); var evalutableExpressionFilterField = compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evalutableExpressionFilter = (IEvaluatableExpressionFilter)evalutableExpressionFilterField.GetValue(null); var databaseField = compiler.GetType().GetField("_database", BindingFlags.NonPublic | BindingFlags.Instance); var database = (IDatabase)databaseField.GetValue(compiler); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(source.Provider); // 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._database._queryCompilationContextFactory var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); var logger = (ISensitiveDataLogger)loggerField.GetValue(queryCompilationContextFactory); // CREATE new query from query visitor var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(source.Expression, queryContext, evaluatableExpressionFilter, logger); //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[] { nodeTypeProvider }); var queryModel = queryparser.GetParsedQuery(newQuery); 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.CreateDefaultQuerySqlGenerator().GenerateSql(queryContext.ParameterValues); return(command); }
protected virtual Expression ExtractParameters([NotNull] Expression query, [NotNull] QueryContext queryContext) { Check.NotNull(query, nameof(query)); Check.NotNull(queryContext, nameof(queryContext)); return(ParameterExtractingExpressionVisitor .ExtractParameters(query, queryContext, _evaluatableExpressionFilter, _logger)); }
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)); }
private static string ToSql <TEntity>(this IQueryable <TEntity> queryable, out IReadOnlyList <DbParameter> parameters, bool isNpgsql) where TEntity : class { var queryCompiler = queryable.Provider.Get <IQueryCompiler>(StaticFields.QueryCompilerField); var queryContextFactory = queryCompiler.Get <IQueryContextFactory>(StaticFields.QueryContextFactoryField); var queryContext = queryContextFactory.Create(); var dbDependencies = queryCompiler.Get <Database>(StaticFields.DataBaseField) .Get <DatabaseDependencies>(StaticFields.DatabaseDependenciesField); var queryCompilationContextFactoryDependencies = dbDependencies.QueryCompilationContextFactory .Get <QueryCompilationContextDependencies>(StaticFields.QueryCompilationContextFactoryDependenciesField); var parameterExtractingExpressionVisitor = new ParameterExtractingExpressionVisitor( (IEvaluatableExpressionFilter)StaticFields.EvaluatableExpressionFilterField.GetValue(queryCompiler), queryContext, queryCompilationContextFactoryDependencies.Logger, true, false); var newQuery = parameterExtractingExpressionVisitor.ExtractParameters(queryable.Expression); var queryparser = (QueryParser)StaticFields.CreateQueryParserMethod .Invoke(queryCompiler, new[] { (INodeTypeProvider)StaticFields.NodeTypeProviderField.GetValue(queryCompiler) }); var queryModel = queryparser.GetParsedQuery(newQuery); var queryModelVisitor = (RelationalQueryModelVisitor)dbDependencies.QueryCompilationContextFactory.Create(false).CreateQueryModelVisitor(); queryModelVisitor.CreateQueryExecutor <TEntity>(queryModel); var sqlCommand = queryModelVisitor.Queries.First().CreateDefaultQuerySqlGenerator().GenerateSql(queryContext.ParameterValues); var dbCommand = isNpgsql ? new NpgsqlCommand(sqlCommand.CommandText) as DbCommand : new SqlCommand(sqlCommand.CommandText) as DbCommand; foreach (var param in sqlCommand.Parameters) { var paramVal = queryContext.ParameterValues[param.InvariantName]; param.AddDbParameter(dbCommand, paramVal); } parameters = dbCommand.Parameters .Cast <DbParameter>() .ToList(); return(sqlCommand.CommandText); }
private Expression ExtractParameters( Expression query, IParameterValues parameterValues, bool parameterize = true, bool generateContextAccessors = false) { var visitor = new ParameterExtractingExpressionVisitor( this.evaluatableExpressionFilter, parameterValues, this.logger, this.currentDbContext.Context, parameterize, generateContextAccessors); return(visitor.ExtractParameters(query)); }
/// <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 virtual Expression ExtractParameters( IDiagnosticsLogger <DbLoggerCategory.Query> logger, Expression query, IParameterValues parameterValues, bool parameterize = true, bool generateContextAccessors = false) { var visitor = new ParameterExtractingExpressionVisitor( _evaluatableExpressionFilter, parameterValues, logger, _currentDbContext.Context, parameterize, generateContextAccessors); return(visitor.ExtractParameters(query)); }
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(out RelationalQueryContext queryContext) { queryContext = null; bool isEFCore2x = false; bool EFCore_2_1 = false; #if EFCORE bool isEFCore3x = EFCoreHelper.IsVersion3x; #endif var context = Query.GetDbContext(); // REFLECTION: Query._context.StateManager #if NETSTANDARD2_0 var stateManager = context.ChangeTracker.GetStateManager(); #else var stateManagerProperty = typeof(DbContext).GetProperty("StateManager", BindingFlags.NonPublic | BindingFlags.Instance); var stateManager = (StateManager)stateManagerProperty.GetValue(context); #endif // REFLECTION: Query._context.StateManager._concurrencyDetector var concurrencyDetectorField = typeof(StateManager).GetField("_concurrencyDetector", BindingFlags.NonPublic | BindingFlags.Instance); var concurrencyDetector = (IConcurrencyDetector)concurrencyDetectorField.GetValue(stateManager); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(Query.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderProperty = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); object nodeTypeProvider; object QueryModelGenerator = null; if (nodeTypeProviderProperty == null) { EFCore_2_1 = true; var QueryModelGeneratorField = queryCompiler.GetType().GetField("_queryModelGenerator", BindingFlags.NonPublic | BindingFlags.Instance); QueryModelGenerator = QueryModelGeneratorField.GetValue(queryCompiler); var nodeTypeProviderField = QueryModelGenerator.GetType().GetField("_nodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); nodeTypeProvider = nodeTypeProviderField.GetValue(QueryModelGenerator); } else { nodeTypeProvider = nodeTypeProviderProperty.GetValue(queryCompiler); } // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); #if NETSTANDARD2_0 QueryParser createQueryParser = null; if (EFCore_2_1) { var queryParserMethod = QueryModelGenerator.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance); createQueryParser = (QueryParser)queryParserMethod.Invoke(QueryModelGenerator, new[] { nodeTypeProvider }); } else { var queryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance); createQueryParser = (QueryParser)queryParserMethod.Invoke(queryCompiler, new[] { nodeTypeProvider }); } #else var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new[] { nodeTypeProvider }); #endif // 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 #if NETSTANDARD2_0 IEvaluatableExpressionFilter evaluatableExpressionFilter = null; if (isEFCore3x) { evaluatableExpressionFilter = (RelationalEvaluatableExpressionFilter)QueryModelGenerator.GetType().GetProperty("EvaluatableExpressionFilter", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(QueryModelGenerator); } else if (EFCore_2_1) { evaluatableExpressionFilter = (IEvaluatableExpressionFilter)QueryModelGenerator.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(QueryModelGenerator); } else { evaluatableExpressionFilter = (IEvaluatableExpressionFilter)queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(queryCompiler); } #else var evaluatableExpressionFilterField = queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evaluatableExpressionFilter = (IEvaluatableExpressionFilter)evaluatableExpressionFilterField.GetValue(null); #endif // 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); IQueryCompilationContextFactory queryCompilationContextFactory; object logger; var dependenciesProperty = typeof(Database).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); if (dependenciesProperty != null) { // EFCore 2.x isEFCore2x = true; var dependencies = dependenciesProperty.GetValue(database); var queryCompilationContextFactoryField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Storage.DatabaseDependencies") .GetProperty("QueryCompilationContextFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(dependencies); var dependenciesProperty2 = typeof(QueryCompilationContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); var dependencies2 = dependenciesProperty2.GetValue(queryCompilationContextFactory); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Query.Internal.QueryCompilationContextDependencies") .GetProperty("Logger", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // (IInterceptingLogger<LoggerCategory.Query>) logger = loggerField.GetValue(dependencies2); } else { // EFCore 1.x // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); logger = loggerField.GetValue(queryCompilationContextFactory); } // CREATE connection { QueryConnection = context.Database.GetService <IRelationalConnection>(); var innerConnection = new CreateEntityConnection(QueryConnection.DbConnection, null); var innerConnectionField = typeof(RelationalConnection).GetField("_connection", BindingFlags.NonPublic | BindingFlags.Instance); var initalConnection = innerConnectionField.GetValue(QueryConnection); #if EFCORE_3X innerConnectionField.SetValue(QueryConnection, innerConnection); #else innerConnectionField.SetValue(QueryConnection, LazyHelper.NewLazy <DbConnection>(() => innerConnection)); #endif RestoreConnection = () => innerConnectionField.SetValue(QueryConnection, initalConnection); } // CREATE query context { var relationalQueryContextType = typeof(RelationalQueryContext); var relationalQueryContextConstructor = relationalQueryContextType.GetConstructors()[0]; // EF Core 1.1 preview if (isEFCore3x) { // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.ExecutionStrategyFactory var executionStrategyFactoryField = queryContextFactory.GetType().GetProperty("ExecutionStrategyFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); var executionStrategyFactory = executionStrategyFactoryField.GetValue(queryContextFactory); var dependenciesProperty3 = typeof(RelationalQueryContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); var dependencies3 = dependenciesProperty3.GetValue(queryContextFactory); queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { dependencies3, createQueryBufferDelegate, QueryConnection, executionStrategyFactory }); } else if (relationalQueryContextConstructor.GetParameters().Length == 5) { // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.ExecutionStrategyFactory var executionStrategyFactoryField = queryContextFactory.GetType().GetProperty("ExecutionStrategyFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); var executionStrategyFactory = executionStrategyFactoryField.GetValue(queryContextFactory); #if !EFCORE_3X var lazyRefStateManager = LazyHelper.NewLazy(() => stateManager); queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, QueryConnection, lazyRefStateManager, concurrencyDetector, executionStrategyFactory }); #endif } else if (isEFCore2x) { // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.ExecutionStrategyFactory var executionStrategyFactoryField = queryContextFactory.GetType().GetProperty("ExecutionStrategyFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); var executionStrategyFactory = executionStrategyFactoryField.GetValue(queryContextFactory); #if !EFCORE_3X var lazyRefStateManager = LazyHelper.NewLazy(() => stateManager); var dependenciesProperty3 = typeof(RelationalQueryContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); var dependencies3 = dependenciesProperty3.GetValue(queryContextFactory); queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { dependencies3, createQueryBufferDelegate, QueryConnection, executionStrategyFactory }); #endif } else { queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, QueryConnection, stateManager, concurrencyDetector }); } } Expression newQuery = null; if (isEFCore3x) { #if EFCORE_3X var visitor = new ParameterExtractingExpressionVisitor(evaluatableExpressionFilter, queryContext, queryContext.GetType(), (IDiagnosticsLogger <DbLoggerCategory.Query>)logger, true, false); newQuery = visitor.ExtractParameters(Query.Expression); #endif //var parameterExtractingExpressionVisitorConstructor = typeof(ParameterExtractingExpressionVisitor).GetConstructors().First(x => x.GetParameters().Length == 6); //var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, queryContext.GetType(), logger, true, false }); //// CREATE new query from query visitor //newQuery = parameterExtractingExpressionVisitor.ExtractParameters(Query.Expression); } else if (isEFCore2x) { var parameterExtractingExpressionVisitorConstructors = typeof(ParameterExtractingExpressionVisitor).GetConstructors(); if (parameterExtractingExpressionVisitorConstructors.Any(x => x.GetParameters().Length == 5)) { // EF Core 2.1 var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 5); var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, true, false }); // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(Query.Expression); } else { var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 6); ParameterExtractingExpressionVisitor parameterExtractingExpressionVisitor = null; if (parameterExtractingExpressionVisitorConstructor.GetParameters().Where(x => x.ParameterType == typeof(DbContext)).Any()) { parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, context, true, false }); } else { parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, null, true, false }); } // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(Query.Expression); } } else { // CREATE new query from query visitor var extractParametersMethods = typeof(ParameterExtractingExpressionVisitor).GetMethod("ExtractParameters", BindingFlags.Public | BindingFlags.Static); newQuery = (Expression)extractParametersMethods.Invoke(null, new object[] { Query.Expression, queryContext, evaluatableExpressionFilter, logger }); } // 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; SelectExpression sqlQuery = null; if (queryModelVisitor.Queries.Count == 0) { var _subQueryModelVisitorsBySource = queryModelVisitor.GetType().GetField("_subQueryModelVisitorsBySource", BindingFlags.NonPublic | BindingFlags.Instance); var subQueryModelVisitorsBySources = (Dictionary <IQuerySource, RelationalQueryModelVisitor>)_subQueryModelVisitorsBySource.GetValue(queryModelVisitor); if (subQueryModelVisitorsBySources.Count == 1) { sqlQuery = subQueryModelVisitorsBySources.First().Value.Queries.First(); } else { throw new Exception("More than one query has been found inside the same query."); } } else { sqlQuery = queryModelVisitor.Queries.First(); } // RETURN the IRelationalCommand #if EFCORE IRelationalCommand relationalCommand = null; var dynamicSqlGenerator = (dynamic)sqlQuery.CreateDefaultQuerySqlGenerator(); if (isEFCore3x) { var commandBuilderFactory = context.Database.GetService <IRelationalCommandBuilderFactory>(); // TODO: Fix null for DbLogger relationalCommand = (IRelationalCommand)dynamicSqlGenerator.GenerateSql(commandBuilderFactory, queryContext.ParameterValues, null); } else { relationalCommand = (IRelationalCommand)dynamicSqlGenerator.GenerateSql(queryContext.ParameterValues); } #else var relationalCommand = sqlQuery.CreateDefaultQuerySqlGenerator().GenerateSql(queryContext.ParameterValues); #endif return(relationalCommand); }
public static IRelationalCommand CreateCommand(this IQueryable source, out RelationalQueryContext queryContext) { bool EFCore_2_1 = false; #if EFCORE bool isEFCore3x = EFCoreHelper.IsVersion3x; #endif var compilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var compiler = compilerField.GetValue(source.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderProperty = compiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); object nodeTypeProvider; object QueryModelGenerator = null; if (nodeTypeProviderProperty == null) { EFCore_2_1 = true; var QueryModelGeneratorField = compiler.GetType().GetField("_queryModelGenerator", BindingFlags.NonPublic | BindingFlags.Instance); QueryModelGenerator = QueryModelGeneratorField.GetValue(compiler); var nodeTypeProviderField = QueryModelGenerator.GetType().GetField("_nodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); nodeTypeProvider = nodeTypeProviderField.GetValue(QueryModelGenerator); } else { nodeTypeProvider = nodeTypeProviderProperty.GetValue(compiler); } var queryContextFactoryField = compiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(compiler); queryContext = (RelationalQueryContext)queryContextFactory.Create(); var databaseField = compiler.GetType().GetField("_database", BindingFlags.NonPublic | BindingFlags.Instance); var database = (IDatabase)databaseField.GetValue(compiler); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(source.Provider); // REFLECTION: Query.Provider._queryCompiler._evaluatableExpressionFilter #if NETSTANDARD2_0 IEvaluatableExpressionFilter evaluatableExpressionFilter = null; if (isEFCore3x) { evaluatableExpressionFilter = (RelationalEvaluatableExpressionFilter)QueryModelGenerator.GetType().GetProperty("EvaluatableExpressionFilter", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(QueryModelGenerator); } else if (EFCore_2_1) { evaluatableExpressionFilter = (IEvaluatableExpressionFilter)QueryModelGenerator.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(QueryModelGenerator); } else { evaluatableExpressionFilter = (IEvaluatableExpressionFilter)compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(queryCompiler); } #else var evalutableExpressionFilterField = compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evalutableExpressionFilter = (IEvaluatableExpressionFilter)evalutableExpressionFilterField.GetValue(null); var evaluatableExpressionFilterField = queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evaluatableExpressionFilter = (IEvaluatableExpressionFilter)evaluatableExpressionFilterField.GetValue(null); #endif Expression newQuery; IQueryCompilationContextFactory queryCompilationContextFactory; var dependenciesProperty = typeof(Database).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); if (dependenciesProperty != null) { var dependencies = dependenciesProperty.GetValue(database); var queryCompilationContextFactoryField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Storage.DatabaseDependencies") .GetProperty("QueryCompilationContextFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(dependencies); var dependenciesProperty2 = typeof(QueryCompilationContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); var dependencies2 = dependenciesProperty2.GetValue(queryCompilationContextFactory); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Query.Internal.QueryCompilationContextDependencies") .GetProperty("Logger", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var logger = loggerField.GetValue(dependencies2); var parameterExtractingExpressionVisitorConstructors = typeof(ParameterExtractingExpressionVisitor).GetConstructors(); if (isEFCore3x) { var parameterExtractingExpressionVisitorConstructor = typeof(ParameterExtractingExpressionVisitor).GetConstructors().First(x => x.GetParameters().Length == 6); var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, queryContext.GetType(), logger, true, false }); // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(source.Expression); } else if (parameterExtractingExpressionVisitorConstructors.Any(x => x.GetParameters().Length == 5)) { // EF Core 2.1 var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 5); var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, true, false }); // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(source.Expression); } else { // EF Core 2.1 Preview 2. var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 6); var _context = queryContext.GetType().GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy); var context = _context.GetValue(queryContext); ParameterExtractingExpressionVisitor parameterExtractingExpressionVisitor = null; if (parameterExtractingExpressionVisitorConstructor.GetParameters().Where(x => x.ParameterType == typeof(DbContext)).Any()) { parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, context, true, false }); } else { parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, null, true, false }); } // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(source.Expression); } } else { // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); var logger = loggerField.GetValue(queryCompilationContextFactory); // CREATE new query from query visitor var extractParametersMethods = typeof(ParameterExtractingExpressionVisitor).GetMethod("ExtractParameters", BindingFlags.Public | BindingFlags.Static); newQuery = (Expression)extractParametersMethods.Invoke(null, new object[] { source.Expression, queryContext, evaluatableExpressionFilter, logger }); //ParameterExtractingExpressionVisitor.ExtractParameters(source.Expression, queryContext, evaluatableExpressionFilter, logger); } //var query = new QueryAnnotatingExpressionVisitor().Visit(source.Expression); //var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(query, queryContext, evalutableExpressionFilter); #if NETSTANDARD2_0 QueryParser queryparser = null; if (EFCore_2_1) { var queryParserMethod = QueryModelGenerator.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance); queryparser = (QueryParser)queryParserMethod.Invoke(QueryModelGenerator, new[] { nodeTypeProvider }); } else { var queryParserMethod = compiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance); queryparser = (QueryParser)queryParserMethod.Invoke(compiler, new[] { nodeTypeProvider }); } #else var queryParserMethod = compiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var queryparser = (QueryParser)queryParserMethod.Invoke(null, new[] { nodeTypeProvider }); #endif var queryModel = queryparser.GetParsedQuery(newQuery); 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]; IRelationalCommand relationalCommand = null; var dynamicSqlGenerator = (dynamic)sqlQuery.CreateDefaultQuerySqlGenerator(); if (isEFCore3x) { var commandBuilderFactory = queryContext.Context.Database.GetService <IRelationalCommandBuilderFactory>(); // TODO: Fix null for DbLogger relationalCommand = (IRelationalCommand)dynamicSqlGenerator.GenerateSql(commandBuilderFactory, queryContext.ParameterValues, null); } else { relationalCommand = (IRelationalCommand)dynamicSqlGenerator.GenerateSql(queryContext.ParameterValues); } return(relationalCommand); }
public static IRelationalCommand CreateCommand <T>(this IQueryable <T> source, out RelationalQueryContext queryContext) { var compilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var compiler = compilerField.GetValue(source.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderField = compiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); var nodeTypeProvider = nodeTypeProviderField.GetValue(compiler); var queryContextFactoryField = compiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(compiler); queryContext = (RelationalQueryContext)queryContextFactory.Create(); var evalutableExpressionFilterField = compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evalutableExpressionFilter = (IEvaluatableExpressionFilter)evalutableExpressionFilterField.GetValue(null); var databaseField = compiler.GetType().GetField("_database", BindingFlags.NonPublic | BindingFlags.Instance); var database = (IDatabase)databaseField.GetValue(compiler); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(source.Provider); // REFLECTION: Query.Provider._queryCompiler._evaluatableExpressionFilter var evaluatableExpressionFilterField = queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static); var evaluatableExpressionFilter = (IEvaluatableExpressionFilter)evaluatableExpressionFilterField.GetValue(null); Expression newQuery; IQueryCompilationContextFactory queryCompilationContextFactory; var dependenciesProperty = typeof(Database).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); if (dependenciesProperty != null) { var dependencies = dependenciesProperty.GetValue(database); var queryCompilationContextFactoryField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Storage.DatabaseDependencies") .GetProperty("QueryCompilationContextFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(dependencies); var dependenciesProperty2 = typeof(QueryCompilationContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); var dependencies2 = dependenciesProperty2.GetValue(queryCompilationContextFactory); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Query.Internal.QueryCompilationContextDependencies") .GetProperty("Logger", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var logger = loggerField.GetValue(dependencies2); var parameterExtractingExpressionVisitorConstructor = typeof(ParameterExtractingExpressionVisitor).GetConstructors().First(x => x.GetParameters().Length == 5); var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, false, false }); // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(source.Expression); } else { // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); var logger = (ISensitiveDataLogger)loggerField.GetValue(queryCompilationContextFactory); // CREATE new query from query visitor newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(source.Expression, queryContext, evaluatableExpressionFilter, logger); } //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 [] { nodeTypeProvider }); var queryModel = queryparser.GetParsedQuery(newQuery); var queryModelVisitor = (RelationalQueryModelVisitor)queryCompilationContextFactory.Create(false).CreateQueryModelVisitor(); var executor = queryModelVisitor.CreateQueryExecutor <T>(queryModel); var queries = queryModelVisitor.Queries; var sqlQuery = queries.ToList()[0]; var command = sqlQuery.CreateDefaultQuerySqlGenerator().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._context.StateManager var stateManagerProperty = typeof(DbContext).GetProperty("StateManager", BindingFlags.NonPublic | BindingFlags.Instance); var stateManager = (StateManager)stateManagerProperty.GetValue(context); // REFLECTION: Query._context.StateManager._concurrencyDetector var concurrencyDetectorField = typeof(StateManager).GetField("_concurrencyDetector", BindingFlags.NonPublic | BindingFlags.Instance); var concurrencyDetector = (IConcurrencyDetector)concurrencyDetectorField.GetValue(stateManager); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(query.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderField = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); var nodeTypeProvider = nodeTypeProviderField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new[] { nodeTypeProvider }); // 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); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); var logger = (ISensitiveDataLogger)loggerField.GetValue(queryCompilationContextFactory); // CREATE connection var queryConnection = new CreateEntityRelationConnection(connection); // CREATE query context var queryContext = new RelationalQueryContext(createQueryBufferDelegate, connection, stateManager, concurrencyDetector); // CREATE new query from query visitor var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(query.Expression, queryContext, evaluatableExpressionFilter, logger); // 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 }
public static IRelationalCommand GetDbCommand <T>(this IQueryable <T> query) { // REFLECTION: Query._context var contextField = query.GetType().GetField("_context", BindingFlags.NonPublic | BindingFlags.Instance); var context = (DbContext)contextField.GetValue(query); // REFLECTION: Query._context.StateManager var stateManagerProperty = typeof(DbContext).GetProperty("StateManager", BindingFlags.NonPublic | BindingFlags.Instance); var stateManager = (StateManager)stateManagerProperty.GetValue(context); // REFLECTION: Query._context.StateManager._concurrencyDetector var concurrencyDetectorField = typeof(StateManager).GetField("_concurrencyDetector", BindingFlags.NonPublic | BindingFlags.Instance); var concurrencyDetector = (IConcurrencyDetector)concurrencyDetectorField.GetValue(stateManager); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(query.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderField = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); var nodeTypeProvider = nodeTypeProviderField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new[] { nodeTypeProvider }); // 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); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); var logger = (ISensitiveDataLogger)loggerField.GetValue(queryCompilationContextFactory); // CREATE query context var queryContext = new RelationalQueryContext(createQueryBufferDelegate, connection, stateManager, concurrencyDetector); // CREATE new query from query visitor var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(query.Expression, queryContext, evaluatableExpressionFilter, logger); // 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); createQueryExecutorMethodGeneric.Invoke(queryModelVisitor, new[] { queryModel }); // RETURN the IRealationCommand var sqlQuery = queryModelVisitor.Queries.First(); var relationalCommand = sqlQuery.CreateDefaultQuerySqlGenerator().GenerateSql(queryContext.ParameterValues); return(relationalCommand); }
public static IRelationalCommand GetDbCommand <T>(this IQueryable <T> query) { bool isEFCore2x = false; // REFLECTION: Query._context var contextField = query.GetType().GetField("_context", BindingFlags.NonPublic | BindingFlags.Instance); var context = (DbContext)contextField.GetValue(query); // REFLECTION: Query._context.StateManager var stateManagerProperty = typeof(DbContext).GetProperty("StateManager", BindingFlags.NonPublic | BindingFlags.Instance); var stateManager = (StateManager)stateManagerProperty.GetValue(context); // REFLECTION: Query._context.StateManager._concurrencyDetector var concurrencyDetectorField = typeof(StateManager).GetField("_concurrencyDetector", BindingFlags.NonPublic | BindingFlags.Instance); var concurrencyDetector = (IConcurrencyDetector)concurrencyDetectorField.GetValue(stateManager); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(query.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderField = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); var nodeTypeProvider = nodeTypeProviderField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new[] { nodeTypeProvider }); // 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 object logger; var dependenciesProperty = typeof(Database).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); IQueryCompilationContextFactory queryCompilationContextFactory; if (dependenciesProperty != null) { // EF Core 2.x isEFCore2x = true; var dependencies = dependenciesProperty.GetValue(database); var queryCompilationContextFactoryField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Storage.DatabaseDependencies") .GetProperty("QueryCompilationContextFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(dependencies); var dependenciesProperty2 = typeof(QueryCompilationContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); var dependencies2 = dependenciesProperty2.GetValue(queryCompilationContextFactory); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Query.Internal.QueryCompilationContextDependencies") .GetProperty("Logger", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // (IInterceptingLogger<LoggerCategory.Query>) logger = loggerField.GetValue(dependencies2); } else { // EF Core 1.x var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); // logger = loggerField.GetValue(queryCompilationContextFactory); } // CREATE query context RelationalQueryContext queryContext; { var relationalQueryContextType = typeof(RelationalQueryContext); var relationalQueryContextConstructor = relationalQueryContextType.GetConstructors()[0]; // EF Core 1.1 preview if (relationalQueryContextConstructor.GetParameters().Length == 5) { // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.ExecutionStrategyFactory var executionStrategyFactoryField = queryContextFactory.GetType().GetProperty("ExecutionStrategyFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); var executionStrategyFactory = executionStrategyFactoryField.GetValue(queryContextFactory); var lazyRefStateManager = new LazyRef <IStateManager>(() => stateManager); queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, connection, lazyRefStateManager, concurrencyDetector, executionStrategyFactory }); } else { queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, connection, stateManager, concurrencyDetector }); } } Expression newQuery; if (isEFCore2x) { var parameterExtractingExpressionVisitorConstructor = typeof(ParameterExtractingExpressionVisitor).GetConstructors().First(x => x.GetParameters().Length == 5); var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, false, false }); // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(query.Expression); } else { // CREATE new query from query visitor newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(query.Expression, queryContext, evaluatableExpressionFilter, (ISensitiveDataLogger)logger); } // 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); createQueryExecutorMethodGeneric.Invoke(queryModelVisitor, new[] { queryModel }); // RETURN the IRealationCommand var sqlQuery = queryModelVisitor.Queries.First(); var relationalCommand = sqlQuery.CreateDefaultQuerySqlGenerator().GenerateSql(queryContext.ParameterValues); return(relationalCommand); }
/// <summary>Creates executor and get command.</summary> /// <returns>The new executor and get command.</returns> public virtual IRelationalCommand CreateExecutorAndGetCommand(out RelationalQueryContext queryContext) { var context = Query.GetDbContext(); // REFLECTION: Query._context.StateManager var stateManagerProperty = typeof(DbContext).GetProperty("StateManager", BindingFlags.NonPublic | BindingFlags.Instance); var stateManager = (StateManager)stateManagerProperty.GetValue(context); // REFLECTION: Query._context.StateManager._concurrencyDetector var concurrencyDetectorField = typeof(StateManager).GetField("_concurrencyDetector", BindingFlags.NonPublic | BindingFlags.Instance); var concurrencyDetector = (IConcurrencyDetector)concurrencyDetectorField.GetValue(stateManager); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(Query.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderField = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); var nodeTypeProvider = nodeTypeProviderField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new[] { nodeTypeProvider }); // 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 relationalQueryContextType = typeof(RelationalQueryContext); var relationalQueryContextConstructor = relationalQueryContextType.GetConstructors()[0]; // EF Core 1.1 preview if (relationalQueryContextConstructor.GetParameters().Length == 5) { // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.ExecutionStrategyFactory var executionStrategyFactoryField = queryContextFactory.GetType().GetProperty("ExecutionStrategyFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); var executionStrategyFactory = executionStrategyFactoryField.GetValue(queryContextFactory); var lazyRefStateManager = new LazyRef <IStateManager>(() => stateManager); queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, QueryConnection, lazyRefStateManager, concurrencyDetector, executionStrategyFactory }); } else { queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, QueryConnection, stateManager, concurrencyDetector }); } } // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); var logger = (ISensitiveDataLogger)loggerField.GetValue(queryCompilationContextFactory); // CREATE new query from query visitor var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(Query.Expression, queryContext, evaluatableExpressionFilter, logger); // 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.CreateDefaultQuerySqlGenerator().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 bool isEFCore2x = false; var list = new List <T>(); var query = (IQueryable <T>)context.Set <T>(); // REFLECTION: Query._context.StateManager var stateManagerProperty = typeof(DbContext).GetProperty("StateManager", BindingFlags.NonPublic | BindingFlags.Instance); var stateManager = (StateManager)stateManagerProperty.GetValue(context); // REFLECTION: Query._context.StateManager._concurrencyDetector var concurrencyDetectorField = typeof(StateManager).GetField("_concurrencyDetector", BindingFlags.NonPublic | BindingFlags.Instance); var concurrencyDetector = (IConcurrencyDetector)concurrencyDetectorField.GetValue(stateManager); // REFLECTION: Query.Provider._queryCompiler var queryCompilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance); var queryCompiler = queryCompilerField.GetValue(query.Provider); // REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic) var nodeTypeProviderField = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance); var nodeTypeProvider = nodeTypeProviderField.GetValue(queryCompiler); // REFLECTION: Query.Provider._queryCompiler.CreateQueryParser(); var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static); var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new[] { nodeTypeProvider }); // 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 object logger; var dependenciesProperty = typeof(Database).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); IQueryCompilationContextFactory queryCompilationContextFactory; if (dependenciesProperty != null) { // EF Core 2.x isEFCore2x = true; var dependencies = dependenciesProperty.GetValue(database); var queryCompilationContextFactoryField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Storage.DatabaseDependencies") .GetProperty("QueryCompilationContextFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(dependencies); var dependenciesProperty2 = typeof(QueryCompilationContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance); var dependencies2 = dependenciesProperty2.GetValue(queryCompilationContextFactory); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = typeof(DbContext).GetTypeFromAssembly_Core("Microsoft.EntityFrameworkCore.Query.Internal.QueryCompilationContextDependencies") .GetProperty("Logger", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // (IInterceptingLogger<LoggerCategory.Query>) logger = loggerField.GetValue(dependencies2); } else { // EF Core 1.x var queryCompilationContextFactoryField = typeof(Database).GetField("_queryCompilationContextFactory", BindingFlags.NonPublic | BindingFlags.Instance); queryCompilationContextFactory = (IQueryCompilationContextFactory)queryCompilationContextFactoryField.GetValue(database); // REFLECTION: Query.Provider._queryCompiler._database._queryCompilationContextFactory.Logger var loggerField = queryCompilationContextFactory.GetType().GetProperty("Logger", BindingFlags.NonPublic | BindingFlags.Instance); // logger = loggerField.GetValue(queryCompilationContextFactory); } // CREATE connection var queryConnection = new CreateEntityRelationConnection(connection); // CREATE query context RelationalQueryContext queryContext; { var relationalQueryContextType = typeof(RelationalQueryContext); var relationalQueryContextConstructor = relationalQueryContextType.GetConstructors()[0]; // EF Core 1.1 preview if (relationalQueryContextConstructor.GetParameters().Length == 5) { // REFLECTION: Query.Provider._queryCompiler._queryContextFactory.ExecutionStrategyFactory var executionStrategyFactoryField = queryContextFactory.GetType().GetProperty("ExecutionStrategyFactory", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); var executionStrategyFactory = executionStrategyFactoryField.GetValue(queryContextFactory); var lazyRefStateManager = new LazyRef <IStateManager>(() => stateManager); queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, connection, lazyRefStateManager, concurrencyDetector, executionStrategyFactory }); } else { queryContext = (RelationalQueryContext)relationalQueryContextConstructor.Invoke(new object[] { createQueryBufferDelegate, connection, stateManager, concurrencyDetector }); } } Expression newQuery; if (isEFCore2x) { var parameterExtractingExpressionVisitorConstructor = typeof(ParameterExtractingExpressionVisitor).GetConstructors().First(x => x.GetParameters().Length == 5); var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, false, false }); // CREATE new query from query visitor newQuery = parameterExtractingExpressionVisitor.ExtractParameters(query.Expression); } else { // CREATE new query from query visitor newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(query.Expression, queryContext, evaluatableExpressionFilter, (ISensitiveDataLogger)logger); } // 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 }