Ejemplo n.º 1
0
//        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);
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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);
        }