Wie kann ich das vom Entity Framework generierte SQL anzeigen?
(In meinem speziellen Fall verwende ich den mysql-Anbieter - falls das eine Rolle spielt)
Wie kann ich das vom Entity Framework generierte SQL anzeigen?
(In meinem speziellen Fall verwende ich den mysql-Anbieter - falls das eine Rolle spielt)
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
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:
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)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;
}
}
}
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.
Es gibt zwei Möglichkeiten:
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.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 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.