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);
        }
示例#2
0
        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);
        }
示例#5
0
    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
    }