1+ using System ;
2+ using System . Linq ;
3+ using System . Reflection ;
4+ using Microsoft . EntityFrameworkCore . Internal ;
5+ using Microsoft . EntityFrameworkCore . Query ;
6+ using Microsoft . EntityFrameworkCore . Query . Internal ;
7+ using Remotion . Linq . Parsing . Structure ;
8+ using Database = Microsoft . EntityFrameworkCore . Storage . Database ;
9+
10+ namespace JsonApiDotNetCoreExampleTests . Helpers . Extensions
11+ {
12+
13+ public static class IQueryableExtensions
14+ {
15+ private static readonly TypeInfo QueryCompilerTypeInfo = typeof ( QueryCompiler ) . GetTypeInfo ( ) ;
16+
17+ private static readonly FieldInfo QueryCompilerField = typeof ( EntityQueryProvider ) . GetTypeInfo ( ) . DeclaredFields . First ( x => x . Name == "_queryCompiler" ) ;
18+
19+ private static readonly PropertyInfo NodeTypeProviderField = QueryCompilerTypeInfo . DeclaredProperties . Single ( x => x . Name == "NodeTypeProvider" ) ;
20+
21+ private static readonly MethodInfo CreateQueryParserMethod = QueryCompilerTypeInfo . DeclaredMethods . First ( x => x . Name == "CreateQueryParser" ) ;
22+
23+ private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo . DeclaredFields . Single ( x => x . Name == "_database" ) ;
24+
25+ private static readonly FieldInfo QueryCompilationContextFactoryField = typeof ( Database ) . GetTypeInfo ( ) . DeclaredFields . Single ( x => x . Name == "_queryCompilationContextFactory" ) ;
26+
27+ public static string ToSql < TEntity > ( this IQueryable < TEntity > query ) where TEntity : class
28+ {
29+ if ( ! ( query is EntityQueryable < TEntity > ) && ! ( query is InternalDbSet < TEntity > ) )
30+ throw new ArgumentException ( "Invalid query" ) ;
31+
32+ var queryCompiler = ( IQueryCompiler ) QueryCompilerField . GetValue ( query . Provider ) ;
33+ var nodeTypeProvider = ( INodeTypeProvider ) NodeTypeProviderField . GetValue ( queryCompiler ) ;
34+ var parser = ( IQueryParser ) CreateQueryParserMethod . Invoke ( queryCompiler , new object [ ] { nodeTypeProvider } ) ;
35+ var queryModel = parser . GetParsedQuery ( query . Expression ) ;
36+ var database = DataBaseField . GetValue ( queryCompiler ) ;
37+ var queryCompilationContextFactory = ( IQueryCompilationContextFactory ) QueryCompilationContextFactoryField . GetValue ( database ) ;
38+ var queryCompilationContext = queryCompilationContextFactory . Create ( false ) ;
39+ var modelVisitor = ( RelationalQueryModelVisitor ) queryCompilationContext . CreateQueryModelVisitor ( ) ;
40+ modelVisitor . CreateQueryExecutor < TEntity > ( queryModel ) ;
41+ var sql = modelVisitor . Queries . First ( ) . ToString ( ) ;
42+
43+ return sql ;
44+ }
45+ }
46+ }
0 commit comments