如何查看实体框架生成的SQL ?

(在我的特殊情况下,我使用mysql提供商-如果它重要)


当前回答

对于那些使用Entity Framework 6及以上版本的用户,如果你想在Visual Studio中查看输出SQL(就像我做的那样),你必须使用新的日志/拦截功能。

添加下面这行代码将在Visual Studio输出面板中输出生成的SQL(以及其他与执行相关的详细信息):

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

有关登录EF6的更多信息,请参阅这个漂亮的博客系列:http://blog.oneunicorn.com/2013/05/08/ef6-sql-logging-part-1-simple-logging/

注意:确保在DEBUG模式下运行项目。

其他回答

我正在做集成测试,需要在实体框架核心2.1中调试生成的SQL语句,所以我使用DebugLoggerProvider或ConsoleLoggerProvider,如下所示:

[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);

        ........

下面是Visual Studio控制台的输出示例:

好吧,目前我正在使用Express分析器,缺点是它只适用于MS SQL Server。你可以在这里找到这个工具:https://expressprofiler.codeplex.com/

SQL Management Studio => Tools => SQL Server分析器

File =>新建跟踪…

使用Template =>空白

事件选择=> T-SQL

左侧检查:SP.StmtComplete

列筛选器可用于选择特定的ApplicationName或DatabaseName

启动该概要文件运行,然后触发查询。

点击这里获取来源信息

使用实体框架核心3.x进行日志记录

实体框架核心通过日志系统发出SQL。只有一些小技巧。您必须指定一个ILoggerFactory和一个筛选器。下面是本文中的一个例子

创建工厂:

var loggerFactory = LoggerFactory.Create(builder =>
{
    builder
    .AddConsole((options) => { })
    .AddFilter((category, level) =>
        category == DbLoggerCategory.Database.Command.Name
        && level == LogLevel.Information);
});

告诉DbContext在onconfigure方法中使用工厂:

optionsBuilder.UseLoggerFactory(_loggerFactory);

从这里,您可以获得更复杂的信息,并与Log方法挂钩以提取有关执行SQL的详细信息。有关完整讨论,请参阅文章。

public class EntityFrameworkSqlLogger : ILogger
{
    #region Fields
    Action<EntityFrameworkSqlLogMessage> _logMessage;
    #endregion
    #region Constructor
    public EntityFrameworkSqlLogger(Action<EntityFrameworkSqlLogMessage> logMessage)
    {
        _logMessage = logMessage;
    }
    #endregion
    #region Implementation
    public IDisposable BeginScope<TState>(TState state)
    {
        return default;
    }
    public bool IsEnabled(LogLevel logLevel)
    {
        return true;
    }
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        if (eventId.Id != 20101)
        {
            //Filter messages that aren't relevant.
            //There may be other types of messages that are relevant for other database platforms...
            return;
        }
        if (state is IReadOnlyList<KeyValuePair<string, object>> keyValuePairList)
        {
            var entityFrameworkSqlLogMessage = new EntityFrameworkSqlLogMessage
            (
                eventId,
                (string)keyValuePairList.FirstOrDefault(k => k.Key == "commandText").Value,
                (string)keyValuePairList.FirstOrDefault(k => k.Key == "parameters").Value,
                (CommandType)keyValuePairList.FirstOrDefault(k => k.Key == "commandType").Value,
                (int)keyValuePairList.FirstOrDefault(k => k.Key == "commandTimeout").Value,
                (string)keyValuePairList.FirstOrDefault(k => k.Key == "elapsed").Value
            );
            _logMessage(entityFrameworkSqlLogMessage);
        }
    }
    #endregion
}

我刚刚做了这个:

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

结果显示在Output:

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