821 Stimmen

Wie kann ich das vom Entity Framework generierte SQL anzeigen?

Wie kann ich das vom Entity Framework generierte SQL anzeigen?

(In meinem speziellen Fall verwende ich den mysql-Anbieter - falls das eine Rolle spielt)

32voto

NullReference Punkte 2588

Anwendbar für EF 6.0 und höher: Für diejenigen unter Ihnen, die mehr über die Protokollierungsfunktionalität wissen wollen und einige der bereits gegebenen Antworten ergänzen möchten.

Jeder Befehl, der von der EF an die Datenbank gesendet wird, kann nun protokolliert werden. Um die generierten Abfragen von EF 6.x anzusehen, verwenden Sie die DBContext.Database.Log property

Was protokolliert wird

 - 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.

Ejemplo:

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(); 
}

Ausgabe:

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

Für die Protokollierung in einer externen Datei:

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();
   }
}

Mehr Informationen hier: Protokollierung und Abfangen von Datenbankoperationen

27voto

Capriols Punkte 239

In EF 4.1 können Sie Folgendes tun:

var result = from x in appEntities
             where x.id = 32
             select x;

System.Diagnostics.Trace.WriteLine(result .ToString());

So erhalten Sie das erzeugte SQL.

20voto

The Red Pea Punkte 14681

Meine Antwort richtet sich an EF Kernstück . Ich verweise auf diese Github-Problem und die Dokumente auf konfigurieren DbContext :

Einfach

Überschreiben Sie die OnConfiguring Methode Ihrer DbContext Klasse ( YourCustomDbContext ) wie hier gezeigt um einen ConsoleLoggerProvider zu verwenden; Ihre Abfragen sollten auf der Konsole protokolliert werden:

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
}

Komplexe

Dieser Komplexe Fall vermeidet das Überschreiben von die DbContext OnConfiguring Methode. , wovon in den Dokumenten abgeraten wird: "Dieser Ansatz eignet sich nicht zum Testen, es sei denn, die Tests zielen auf die gesamte Datenbank ab."

Dieser Komplexe Fall verwendet:

  • El IServiceCollection en Startup Klasse ConfigureServices Methode (anstelle des Überschreibens der OnConfiguring Methode; der Vorteil ist eine lockerere Kopplung zwischen der DbContext und die ILoggerProvider die Sie verwenden möchten)
  • Eine Implementierung von ILoggerProvider (anstelle der Verwendung des ConsoleLoggerProvider Implementierung oben gezeigt; der Vorteil ist, dass unsere Implementierung zeigt, wie wir in File protokollieren würden (ich sehe keine File Logging Provider wird mit EF Core ausgeliefert ))

Zum Beispiel so:

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));
        ...
    }
}

Hier ist die Implementierung eines MyLoggerProvider (und seine MyLogger die ihre Protokolle an eine Datei anhängt, die Sie konfigurieren können; Ihre EF Core-Abfragen werden in der Datei erscheinen).

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;
        }
    } 
}

17voto

Gerrie Pretorius Punkte 2743

Um die Abfrage immer griffbereit zu haben, ohne den Code zu ändern fügen Sie dies zu Ihrem DbContext hinzu und überprüfen Sie es im Ausgabefenster in Visual Studio.

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

Ähnlich wie die Antwort von @Matt Nibecker, aber damit müssen Sie es nicht jedes Mal in Ihren aktuellen Code einfügen, wenn Sie die Abfrage benötigen.

14voto

Benjamin Pollack Punkte 26402

Es gibt zwei Möglichkeiten:

  1. Um das generierte SQL zu sehen, rufen Sie einfach ToTraceString() . Sie können es in Ihr Überwachungsfenster einfügen und einen Haltepunkt setzen, um zu sehen, was die Abfrage zu einem bestimmten Zeitpunkt für jede LINQ-Abfrage wäre.
  2. Sie können einen Tracer an den SQL-Server Ihrer Wahl anhängen, der Ihnen die endgültige Abfrage in all ihren blutigen Details anzeigt. Im Falle von MySQL ist es am einfachsten, die Abfragen zu verfolgen, indem Sie das Abfrageprotokoll mit tail -f . Mehr über die Logging-Möglichkeiten von MySQL erfahren Sie in die offizielle Dokumentation . Für SQL Server ist es am einfachsten, den mitgelieferten SQL Server Profiler zu verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X