Come faccio a visualizzare il codice SQL generato da Entity Framework?

Come faccio a visualizzare il codice SQL generato da entity framework ?

(Nel mio caso In particolare sto usando mysql provider se è importante)

  • Questo articolo di MSDN Magazine descrive alcune opzioni per i profili per Entity Framework 4
  • Collegato “duplicare” la domanda è per LINQ to SQL, quindi non è un duplicato.
  • Quando si esegue con un debugger, IntelliTrace mostra query SQL fatto, ma senza risultati.
  • Se siete interessati a vedere le istruzioni SQL di sviluppo, è possibile utilizzare LINQPad. Quando si esegue una query LINQ e i risultati che ci sarà un SQL scheda che mostra l’istruzione SQL eseguita. Per mySQL devi installare un driver. Non ho un database mySQL disponibile, ma dovrebbe funzionare.
InformationsquelleAutor nos | 2009-09-11

 

18 Replies
  1. 441

    È possibile effettuare le seguenti operazioni:

    IQueryable query = from x in appEntities
                 where x.id = 32
                 select x;
    
    var sql = ((System.Data.Objects.ObjectQuery)query).ToTraceString();

    o in EF6:

    var sql = ((System.Data.Entity.Core.Objects.ObjectQuery)query)
                .ToTraceString();

    Che vi darà l’SQL generato.

    • Funziona con MySQL troppo.
    • Non ottenere SQL per le query che terminano con .Singolo(), .Count ().Qualsiasi(), etc. che modo.
    • Che è perché dopo l’esecuzione di .Single() il tuo oggetto non è più IQueryable credo.
    • con EF6, ho potuto ottenere solo con la riflessione. ma prima, ho dovuto convertire la result per System.Data.Entity.Infrastructure.DbQuery<T>, per poi arrivare proprietà interna InternalQuery come (System.Data.Entity.Internal.Linq.InternalQuery<T>), e solo allora, utilizzare ToTraceString()
    • aggiungi riferimento per il Sistema.Dati.Entità Del Sistema.Dati.Oggetti.ObjectQuery esiste sopra, dll
    • questo ToTraceString() ritorno query finale (con i parametri già collegato) o ritornerà la query senza parametri? cioè: la query di variabili come p__linq__i?
    • anche Sistema.Dati.Gli oggetti non sono più disponibili in EF 6
    • re:EF 6, del Sistema.Dati.Gli oggetti non vengono rimossi.. in realtà è qui: il Sistema.Dati.Entità.Core.Oggetti.ObjectQuery
    • In EF6 si può solo fare result.ToString()
    • Restituisce la query, ma senza valori vincolanti.
    • Mi piacerebbe avere il sql comandi per il mio add e update operazioni, sembra che questi metodi funzionano solo con select comando?
    • Credo che dovrebbe essere where x.id == 32? Il codice è =.
    • Questo non funziona in EF Core. Qual è l’alternativa per EF Core?
    • Non sembra funzionare quando la query è un DTO come IQueryable<MyDto> Eccezione Messaggio = “Impossibile eseguire il cast di oggetti di tipo ‘System.Dati.Entità.Infrastruttura.DbQuery`1[Mio.I controller.MyDto]’ di tipo ‘System.Dati.Entità.Core.Oggetti.ObjectQuery’.”
    • In EF6 utilizzando ((System.Data.Entity.Core.Objects.ObjectQuery)query).ToTraceString() ho “buttato un’eccezione di tipo ‘System.InvalidCastException” dei messaggi. perché? Utilizzando query.ToString()’ posso vedere tutto l’albero, ma non di SQL.
    • Che non funziona nella EF6; ho dovuto cambiare il cast di DbQuery<T>, ad esempio: var sql = ((System.Data.Entity.Infrastructure.DbQuery<MyEntity>)query).Sql;
    • Non vedo come che sta per darvi il valore del parametro però. ( che cos’è .Sql per ? )

  2. 881

    Per chi l’utilizzo di Entity Framework 6 e, se si desidera visualizzare l’output di SQL in Visual Studio (come ho fatto io) devi utilizzare la nuova registrazione/intercettazione funzionalità.

    Aggiungendo la seguente linea di sputare fuori l’SQL generato (con supplementari di esecuzione relativi dettagli) in Visual Studio pannello output:

    using (MyDatabaseEntities context = new MyDatabaseEntities())
    {
        context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
        //query the database using EF here.
    }

    Ulteriori informazioni sulla registrazione in EF6 in questa stupenda serie di blog: http://blog.oneunicorn.com/2013/05/08/ef6-sql-logging-part-1-simple-logging/

    Nota: assicurarsi che si sta eseguendo il vostro progetto in modalità di DEBUG.

    • Questa risposta merita più amore (se si utilizza EF6+) – grande debug oltre, basta aggiungere il DBContext costruttore di questo.Database.Log = …)
    • in realtà, io sto usando EF6.1.0; e come lei ha detto, non il suo lavoro durante la costruzione affermando: Impossibile creare delegato con ‘Sistema.Diagnostica.Debug.WriteLine(string)’ perché ha un attributo Condizionale. Tuttavia la risposta sopra funziona bene!
    • Devo riformulare il mio commento o rimuovere, infatti, senza lambda funziona solo dalla Finestra di Comando.
    • Assicurarsi che si sta eseguendo il vostro progetto in MODALITÀ di DEBUG, controllare se la voce “Debug” è selezionato nella combobox del riquadro Output e di controllare anche se il debug non è redirezione Immediata (Strumenti > Opzioni > Debug > Reindirizzare l’Output di testo della Finestra a Finestra Immediata)
    • c’è un modo per ottenere questo per includere i valori delle variabili direttamente all’interno di sql generato? Po ‘ di dolore, con i più grandi.
    • SÌ. o utilizzare qualcosa come Serilog etc. context.Database.Log = s => Log.Verbose(s);
    • Per coloro che utilizzano un DataContext, ma sono imbattuto qui, è possibile utilizzare DataContext.Log msdn.microsoft.com/en-us/library/…
    • Nibecker Questo non funziona in EF Core. Qual è l’alternativa per EF Core?
    • Purtroppo qualunque cosa si utilizza assegnare .Registro sarà chiamato più volte per query (aperto conn, prima parte di sql, più parti di sql, conn close).
    • molto utile! Sembra context.Database.Log = Debug.WriteLine; non funziona.. si sepecifically andare come ... s => ...(s); , il modo in cui è la tua risposta!
    • Hm, non funziona quando si esegue il debug il mio test di unità. Ho messo l’istruzione del costruttore del mio DbContext.
    • ATTENZIONE: ho implementato questo con l’intenzione di farlo solo in esecuzione in via di sviluppo. Quando abbiamo distribuito il nostro ambiente di test, abbiamo iniziato improvvisamente vedere le perdite di memoria nel Processo di lavoro IIS. Dopo i profili di memoria, ci siamo resi conto anche esplicita GC non era raccolta l’entità contesto oggetti più (sì, erano in uso consolidato). La rimozione di questa linea tornato tutto alla normalità. Così, mentre questo è un grande strumento, assicurarsi di costruire solo in app per lo sviluppo.
    • O basta aggiungere alla tua concreta costruttore: public MyDbContext() : base("name=MyDbContext") { Database.Log = sql => System.Diagnostics.Debug.WriteLine(sql); }
    • Come può questo essere configurato utilizzando ASP.NET Core? Il DbContext viene iniettato automaticamente e non abbiamo il controllo, la creazione di esso.
    • Per chi cerca VB: stackoverflow.com/a/33300670/1381490
    • come si fa a fare questo per core?

  3. 77

    Se si utilizza un DbContext, è possibile effettuare le seguenti operazioni per ottenere il SQL:

    var result = from i in myContext.appEntities
                 select new Model
                 {
                     field = i.stuff,
                 };
    var sql = result.ToString();
    • ToString() vi darà la query con le variabili in esso, come p__linq__0, anziché i valori finali (ad esempio: 34563 invece di p__linq__0)
  4. 77

    A partire EF6.1 è possibile utilizzare Intercettori per registrare un database logger.
    Vedere i capitoli “Interceptor” e “Database di Registrazione delle Operazioni” per un File qui

    <interceptors> 
      <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework"> 
        <parameters> 
          <parameter value="C:\Temp\LogOutput.txt"/> 
          <parameter value="true" type="System.Boolean"/> 
        </parameters> 
      </interceptor> 
    </interceptors>
  5. 21

    Applicabili per EF 6.0 e versioni successive:
    Per quelli di voi che vogliono sapere di più sulle funzionalità di registrazione e l’aggiunta di alcune risposte già date.

    Ogni comando inviato dal EF per il database può ora essere registrato. Per visualizzare le query generate da EF 6.x, utilizzare il DBContext.Database.Log property

    Ciò Che Viene Registrato

     - SQL for all different kinds of commands. For example:
        - Queries, including normal LINQ queries, eSQL queries, and raw queries from methods such as SqlQuery.
        - Inserts, updates, and deletes generated as part of SaveChanges
        - Relationship loading queries such as those generated by lazy loading
     - Parameters
     - Whether or not the command is being executed asynchronously
     - A timestamp indicating when the command started executing
     - Whether or not the command completed successfully, failed by throwing an exception, or, for async, was canceled
     - Some indication of the result value
     - The approximate amount of time it took to execute the command. Note that this is the time from sending the command to getting the result object back. It does not include time to read the results.

    Esempio:

    using (var context = new BlogContext()) 
    { 
        context.Database.Log = Console.Write; 
    
        var blog = context.Blogs.First(b => b.Title == "One Unicorn"); 
    
        blog.Posts.First().Title = "Green Eggs and Ham"; 
    
        blog.Posts.Add(new Post { Title = "I do not like them!" }); 
    
        context.SaveChangesAsync().Wait(); 
    }

    Di uscita:

    SELECT TOP (1)
        [Extent1].[Id] AS [Id],
        [Extent1].[Title] AS [Title]
        FROM [dbo].[Blogs] AS [Extent1]
        WHERE (N'One Unicorn' = [Extent1].[Title]) AND ([Extent1].[Title] IS NOT NULL)
    -- Executing at 10/8/2013 10:55:41 AM -07:00
    -- Completed in 4 ms with result: SqlDataReader
    
    SELECT
        [Extent1].[Id] AS [Id],
        [Extent1].[Title] AS [Title],
        [Extent1].[BlogId] AS [BlogId]
        FROM [dbo].[Posts] AS [Extent1]
        WHERE [Extent1].[BlogId] = @EntityKeyValue1
    -- EntityKeyValue1: '1' (Type = Int32)
    -- Executing at 10/8/2013 10:55:41 AM -07:00
    -- Completed in 2 ms with result: SqlDataReader
    
    UPDATE [dbo].[Posts]
    SET [Title] = @0
    WHERE ([Id] = @1)
    -- @0: 'Green Eggs and Ham' (Type = String, Size = -1)
    -- @1: '1' (Type = Int32)
    -- Executing asynchronously at 10/8/2013 10:55:41 AM -07:00
    -- Completed in 12 ms with result: 1
    
    INSERT [dbo].[Posts]([Title], [BlogId])
    VALUES (@0, @1)
    SELECT [Id]
    FROM [dbo].[Posts]
    WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
    -- @0: 'I do not like them!' (Type = String, Size = -1)
    -- @1: '1' (Type = Int32)
    -- Executing asynchronously at 10/8/2013 10:55:41 AM -07:00
    -- Completed in 2 ms with result: SqlDataReader

    Di accedere a un file esterno:

    using (var context = new BlogContext()) 
    {  
        using (var sqlLogFile = new StreamWriter("C:\\temp\\LogFile.txt"))
        {          
             context.Database.Log = sqlLogFile.Write;     
             var blog = context.Blogs.First(b => b.Title == "One Unicorn"); 
             blog.Posts.First().Title = "Green Eggs and Ham"; 
             context.SaveChanges();
       }
    }

    Più info qui: Di registrazione e di Intercettare le Operazioni di Database

  6. 17

    Si possono fare le seguenti in EF 4.1:

    var result = from x in appEntities
                 where x.id = 32
                 select x;
    
    System.Diagnostics.Trace.WriteLine(result .ToString());

    Che vi darà l’SQL generato.

    • Di fatto, credo che questo funziona solo se la query restituisce un tipo anonimo. Se restituisce un tipo personalizzato, il ToString() di uscita è lo spazio dei nomi di che tipo personalizzato. Per esempio, se il codice di cui sopra è stato select new CustomType { x = x.Name }, il valore restituito sarà qualcosa di Company.Models.CustomType invece di SQL generato.
    • Questa tecnica produce System.Data.Objects.ObjectQuery``1[MyProject.Models.Product] per me.
    • Sistema.Dati.Oggetti.ObjectQuery non è EF 4.1 (DbContext). Utilizzando DbContext sarebbe di Sistema.Dati.Entità.Infrastruttura.DbQuery`1[MyProject.Modelli.Prodotto] che, di fatto, uscite è di SQL in una chiamata a “ToString()”
    • Questo vi darà l’SQL generato, dove, nella finestra di output? quale opzione dal menu a discesa?
  7. 16

    Ci sono due modi:

    1. Per visualizzare l’SQL che verrà generato, è sufficiente chiamare ToTraceString(). È possibile aggiungere nella vostra finestra di controllo e impostare un punto di interruzione per vedere che cosa la query potrebbe essere in un qualsiasi punto per ogni query LINQ.
    2. È possibile allegare un tracciante per SQL server a scelta, di cui vi mostriamo le query finale in tutti i suoi dettagli scabrosi. Nel caso di MySQL, il modo più semplice per tracciare la query è semplicemente quello di coda il log di query con tail -f. Si può imparare di più su MySQL servizi di accesso in la documentazione ufficiale. Per SQL Server, il modo più semplice è quello di utilizzare il SQL Server profiler.
    • Il ToTraceString di cosa ?
    • Il ObjectQuery, come Nick notato subito dopo che ho postato la mia risposta.
    • SQL Server Profiler cattura i primi 4000 caratteri, ma EF query può essere molto più a lungo.
  8. 11

    La mia risposta indirizzi EF core. Ho il riferimento di questa github problema, e la documentazione la configurazione di DbContext:

    Semplice

    Ignorare il OnConfiguring metodo di DbContext classe (YourCustomDbContext) come illustrato di seguito per l’utilizzo di un ConsoleLoggerProvider; le query deve accedere alla console:

    public class YourCustomDbContext : DbContext
    {
        #region DefineLoggerFactory
        public static readonly LoggerFactory MyLoggerFactory
            = new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
        #endregion
    
    
        #region RegisterLoggerFactory
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            => optionsBuilder
                .UseLoggerFactory(MyLoggerFactory); //Warning: Do not create a new ILoggerFactory instance each time                
        #endregion
    }

    Complesso

    Questo Complesso caso evita di sovrascrivere DbContext OnConfiguring metodo. , che è sconsigliata nei documenti: “Questo approccio non si presta a sperimentazioni, a meno che il test di destinazione completo del database.”

    Questo caso Complesso che utilizza:

    • Il IServiceCollection in Startup classe ConfigureServices metodo
      (invece di eseguire l’override del OnConfiguring metodo; il beneficio è un perdente di accoppiamento tra il DbContext e il ILoggerProvider che si desidera utilizzare)
    • Un’implementazione di ILoggerProvider (invece di usare il ConsoleLoggerProvider attuazione sopra indicato; vantaggio è la nostra implementazione mostra come sarebbe possibile accedere al File (non vedo un Per la Registrazione di File Provider fornito con EF Core))

    Come questo:

    public class Startup
    
        public void ConfigureServices(IServiceCollection services)
        {
            ...
            var lf = new LoggerFactory();
            lf.AddProvider(new MyLoggerProvider());
    
            services.AddDbContext<YOUR_DB_CONTEXT>(optionsBuilder => optionsBuilder
                    .UseSqlServer(connection_string)
                    //Using the LoggerFactory 
                    .UseLoggerFactory(lf));
            ...
        }
    }

    Ecco l’attuazione di un MyLoggerProvider (e la sua MyLogger che aggiunge i propri log di un File è possibile configurare; EF Core query verranno visualizzate nel file.)

    public class MyLoggerProvider : ILoggerProvider
    {
        public ILogger CreateLogger(string categoryName)
        {
            return new MyLogger();
        }
    
        public void Dispose()
        { }
    
        private class MyLogger : ILogger
        {
            public bool IsEnabled(LogLevel logLevel)
            {
                return true;
            }
    
            public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
            {
                File.AppendAllText(@"C:\temp\log.txt", formatter(state, exception));
                Console.WriteLine(formatter(state, exception));
            }
    
            public IDisposable BeginScope<TState>(TState state)
            {
                return null;
            }
        } 
    }
    • Quindi…non c’è principianti modo di farlo?
    • Ho semplificato la mia risposta; provare l’alternativa più semplice
  9. 6

    Avere la query sempre a portata di mano, senza modificare il codice
    aggiungere questo al tuo DbContext e controllare la finestra di output di visual studio.

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Database.Log = (query)=> Debug.Write(query);
        }

    Simile a @Matt Nibecker risposta, ma con questo non è necessario aggiungere al tuo attuale codice, ogni volta che avete bisogno di query.

    • La migliore risposta!
  10. 4
    IQueryable query = from x in appEntities
                       where x.id = 32
                       select x;
    var queryString = query.ToString();

    Tornerà la query sql. Di lavoro utilizzo di datacontext di entity framework 6

    • Ho appena provato e ne è traccia oggetto: Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[Sistema.Linq.IGrouping2[System.Int32,String]] invece di query reale. Mi manca qualcosa o hai dimenticato di dire qualcosa?
  11. 4

    Sto facendo test di integrazione, e aveva bisogno di questo per il debug, l’istruzione SQL generata in Entity Framework Core 2.1, così io uso DebugLoggerProvider o ConsoleLoggerProvider in questo modo:

    [Fact]
    public async Task MyAwesomeTest
        {
            //setup log to debug sql queries
            var loggerFactory = new LoggerFactory();
            loggerFactory.AddProvider(new DebugLoggerProvider());
            loggerFactory.AddProvider(new ConsoleLoggerProvider(new ConsoleLoggerSettings()));
    
            var builder = new DbContextOptionsBuilder<DbContext>();
            builder
                .UseSqlServer("my connection string") //"Server=.;Initial Catalog=TestDb;Integrated Security=True"
                .UseLoggerFactory(loggerFactory);
    
            var dbContext = new DbContext(builder.Options);
    
            ........

    Ecco un esempio di output da console di Visual Studio:

    Come faccio a visualizzare il codice SQL generato da Entity Framework?

  12. 3

    SQL Management Studio => Strumenti => SQL Server profiler

    File => Nuova Traccia…

    Utilizzare il Template => Vuoto

    Evento di selezione => T-SQL

    Lefthandside verificare: SP.StmtComplete

    Filtri di colonna può essere utilizzato per selezionare una specifica ApplicationName o DatabaseName

    Avviare tale profilo l’esecuzione di innescare la query.

    Clicca qui per Fonte informazioni

    • mi dispiace molto per SQL server, MySQL
  13. 2

    Nel mio caso per EF 6+, invece di utilizzare questo nella Finestra Immediata per trovare la stringa di query:

    var sql = ((System.Data.Entity.Core.Objects.ObjectQuery)query).ToTraceString();

    Ho finito per ottenere il codice SQL generato comando:

    var sql = ((System.Data.Entity.Infrastructure.DbQuery<<>f__AnonymousType3<string,string,string,short,string>>)query).ToString();

    Naturalmente, il vostro tipo anonimo firma potrebbe essere diverso.

    HTH.

  14. 2

    Ho fatto questo:

    IQueryable<Product> query = EntitySet.Where(p => p.Id == id);
    Debug.WriteLine(query);

    E il risultato indicato nella Uscita:

    SELECT 
        [Extent1].[Id] AS [Id], 
        [Extent1].[Code] AS [Code], 
        [Extent1].[Name] AS [Name], 
        [Extent2].[Id] AS [Id1], 
        [Extent2].[FileName] AS [FileName], 
        FROM  [dbo].[Products] AS [Extent1]
        INNER JOIN [dbo].[PersistedFiles] AS [Extent2] ON [Extent1].[PersistedFileId] = [Extent2].[Id]
        WHERE [Extent1].[Id] = @p__linq__0
    • Sì, ma credo che Nessuno vuole vedere il p__linq__io , ma i valori reali
    • In questo modo funziona ancora in EF 6 e sarà utile solo se si cura di ciò che la struttura della query simile. Nel mio caso il progetto di creare il IQueryable<T> oggetto non dispone di riferimento per il Sistema.Dati.Entità né voglio aggiungere solo per il debugging. Quindi, questo metodo ha funzionato bene.
  15. 2

    Per me, utilizzando EF6 e Visual Studio 2015 sono entrato query nella finestra immediata e mi ha dato l’Istruzione SQL generata

  16. 2

    Necromancing.

    Questa pagina è il primo risultato della ricerca, quando la ricerca di una soluzione per qualsiasi .NET Framework, in modo che qui, come un servizio pubblico, come si è fatto in EntityFrameworkCore (per .NET Core 1 & 2):

    var someQuery = (
        from projects in _context.projects
        join issues in _context.issues on projects.Id equals issues.ProjectId into tmpMapp
        from issues in tmpMapp.DefaultIfEmpty()
        select issues
    ) //.ToList()
    ;
    
    //string sql = someQuery.ToString();
    //string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions.ToSql(someQuery);
    //string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions1.ToSql(someQuery);
    //using Microsoft.EntityFrameworkCore;
    string sql = someQuery.ToSql();
    System.Console.WriteLine(sql);

    E poi questi metodi di estensione (IQueryableExtensions1 per .NET Core 1.0, IQueryableExtensions per .NET Core 2.0) :

    using System;
    using System.Linq;
    using System.Reflection;
    using Microsoft.EntityFrameworkCore.Internal;
    using Microsoft.EntityFrameworkCore.Query;
    using Microsoft.EntityFrameworkCore.Query.Internal;
    using Microsoft.EntityFrameworkCore.Storage;
    using Remotion.Linq.Parsing.Structure;
    
    
    namespace Microsoft.EntityFrameworkCore
    {
    
        //https://stackoverflow.com/questions/1412863/how-do-i-view-the-sql-generated-by-the-entity-framework
        //http://rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/
    
        public static class IQueryableExtensions
        {
            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 class IQueryableExtensions1
        {
            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 FieldInfo QueryCompilationContextFactoryField = typeof(Database).GetTypeInfo()
                .DeclaredFields.Single(x => x.Name == "_queryCompilationContextFactory");
    
    
            public static string ToSql<TEntity>(IQueryable<TEntity> query) where TEntity : class
            {
                if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>))
                {
                    throw new ArgumentException("Invalid query");
                }
    
                var queryCompiler = (IQueryCompiler) 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 queryCompilationContextFactory =
                    (IQueryCompilationContextFactory) QueryCompilationContextFactoryField.GetValue(database);
                var queryCompilationContext = queryCompilationContextFactory.Create(false);
                var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
                modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
                var sql = modelVisitor.Queries.First().ToString();
    
                return sql;
            }
    
    
        }
    
    
    }
    • Sto usando EF Core 2.0.1 e il suggerimento precedente risultati: Sistema.InvalidCastException: “Impossibile eseguire il cast di oggetti di tipo Microsoft.EntityFrameworkCore.Query.Interno.InMemoryQueryModelVisitor’ di tipo “Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor” per la linea: var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
    • se si segue l’autore originale del gist è possibile trovare qualcuno che fornito una versione aggiornata di tale metodo di estensione. Ha funzionato per me.
  17. 1

    Se si desidera avere i valori di parametro (non solo @p_linq_0, ma anche i loro valori), si può utilizzare IDbCommandInterceptor e aggiungere qualche registrazione per ReaderExecuted metodo.

    • Puoi mostrare un esempio?

Lascia un commento