// private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo(); // // private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields.First(x => x.Name == "_queryCompiler"); // // private static readonly PropertyInfo NodeTypeProviderField = QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider"); // // private static readonly MethodInfo CreateQueryParserMethod = QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser"); // // private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database"); // // private static readonly PropertyInfo DatabaseDependenciesField = typeof(Database).GetTypeInfo().DeclaredProperties.Single(x => x.Name == "Dependencies"); // // public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class // { // if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>)) // { // throw new ArgumentException("Invalid query"); // } // // var queryCompiler = (QueryCompiler)QueryCompilerField.GetValue(query.Provider); // var nodeTypeProvider = (INodeTypeProvider)NodeTypeProviderField.GetValue(queryCompiler); // var parser = (IQueryParser)CreateQueryParserMethod.Invoke(queryCompiler, new object[] { nodeTypeProvider }); // var queryModel = parser.GetParsedQuery(query.Expression); // var database = DataBaseField.GetValue(queryCompiler); // var databaseDependencies = (DatabaseDependencies)DatabaseDependenciesField.GetValue(database); // var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false); // var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); // modelVisitor.CreateQueryExecutor<TEntity>(queryModel); // var sql = modelVisitor.Queries.First().ToString(); // // return sql; // } public static string ToSql <TEntity>(this IQueryable <TEntity> query, DbContext dbCtx) { try { IQueryModelGenerator modelGenerator = dbCtx.GetService <IQueryModelGenerator>(); QueryModel queryModel = modelGenerator.ParseQuery(query.Expression); DatabaseDependencies databaseDependencies = dbCtx.GetService <DatabaseDependencies>(); QueryCompilationContext queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false); RelationalQueryModelVisitor modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); modelVisitor.CreateQueryExecutor <TEntity>(queryModel); var sql = modelVisitor.Queries.First().ToString(); return(sql); } catch (Exception ex) { return(ex.Message); } }
public static (SelectExpression, IReadOnlyDictionary <string, object>) Compile( this DbContext dbContext, Expression linqExpression) { QueryContext queryContext = dbContext.GetService <IQueryContextFactory>().Create(); IEvaluatableExpressionFilter evaluatableExpressionFilter = dbContext.GetService <IEvaluatableExpressionFilter>(); linqExpression = new ParameterExtractingExpressionVisitor( evaluatableExpressionFilter: evaluatableExpressionFilter, parameterValues: queryContext, logger: dbContext.GetService <IDiagnosticsLogger <DbLoggerCategory.Query> >(), context: dbContext, parameterize: true).ExtractParameters(linqExpression); QueryParser queryParser = new QueryParser(new ExpressionTreeParser( nodeTypeProvider: dbContext.GetService <INodeTypeProviderFactory>().Create(), processor: new CompoundExpressionTreeProcessor(new IExpressionTreeProcessor[] { new PartialEvaluatingExpressionTreeProcessor(evaluatableExpressionFilter), new TransformingExpressionTreeProcessor(ExpressionTransformerRegistry.CreateDefault()) }))); QueryModel queryModel = queryParser.GetParsedQuery(linqExpression); Type resultType = queryModel.GetResultType(); if (resultType.IsConstructedGenericType && resultType.GetGenericTypeDefinition() == typeof(IQueryable <>)) { resultType = resultType.GenericTypeArguments.Single(); } QueryCompilationContext compilationContext = dbContext.GetService <IQueryCompilationContextFactory>() .Create(async: false); RelationalQueryModelVisitor queryModelVisitor = (RelationalQueryModelVisitor)compilationContext .CreateQueryModelVisitor(); queryModelVisitor.GetType() .GetMethod(nameof(RelationalQueryModelVisitor.CreateQueryExecutor)) .MakeGenericMethod(resultType) .Invoke(queryModelVisitor, new object[] { queryModel }); SelectExpression databaseExpression = queryModelVisitor.TryGetQuery(queryModel.MainFromClause); databaseExpression.QuerySource = queryModel.MainFromClause; return(databaseExpression, queryContext.ParameterValues); }
public static string ToSql <TEntity>(this IQueryable <TEntity> queryable) where TEntity : class { if (!(queryable is EntityQueryable <TEntity>) && !(queryable is InternalDbSet <TEntity>)) { throw new ArgumentException(); } IQueryCompiler queryCompiler = (IQueryCompiler)_queryCompilerField.GetValue(queryable.Provider); IQueryModelGenerator queryModelGenerator = (IQueryModelGenerator)_queryModelGeneratorField.GetValue(queryCompiler); QueryModel queryModel = queryModelGenerator.ParseQuery(queryable.Expression); object database = _databaseField.GetValue(queryCompiler); IQueryCompilationContextFactory queryCompilationContextFactory = ((DatabaseDependencies)_dependenciesProperty.GetValue(database)).QueryCompilationContextFactory; QueryCompilationContext queryCompilationContext = queryCompilationContextFactory.Create(false); RelationalQueryModelVisitor modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); modelVisitor.CreateQueryExecutor <TEntity>(queryModel); return(modelVisitor.Queries.Join(Environment.NewLine + Environment.NewLine)); }
public static string ToSql <TEntity>(this IQueryable <TEntity> query) where TEntity : class { QueryCompiler queryCompiler = (QueryCompiler)QueryCompilerField.GetValue(query.Provider); QueryModelGenerator modelGenerator = (QueryModelGenerator)QueryModelGeneratorField.GetValue(queryCompiler); Remotion.Linq.QueryModel queryModel = modelGenerator.ParseQuery(query.Expression); IDatabase database = (IDatabase)DataBaseField.GetValue(queryCompiler); DatabaseDependencies databaseDependencies = (DatabaseDependencies)DatabaseDependenciesField.GetValue(database); QueryCompilationContext queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false); RelationalQueryModelVisitor modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); modelVisitor.CreateQueryExecutor <TEntity>(queryModel); string sql = modelVisitor.Queries.First().ToString(); return(sql); }