如何使用Entity Framework 7记录查询?

Mah*_*Ali 13 entity-framework entity-framework-core

我在夜间构建频道上使用Entity Framework 7(现在我正在使用版本EntityFramework.7.0.0-beta2-11524)并且我试图仅仅出于好奇而记录EF生成的查询.

我正在编写一个简单的控制台程序,我尝试使用 EF6 相同的日志记录技术,但DbContext.Database.Log在Entity Framework 7上不可用.有没有办法记录或只是看看EF7生成的SQL?

Bob*_*les 8

对于那些使用EF7的人来说,上述都不适用于我.但这就是我如何运作的方式.(来自@avi cherry的评论)

在您的Startup.cs中,您可以使用配置方法,其中包含一系列配置.它应该如下所示(除了你的东西).

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        //this is the magic line
        loggerFactory.AddDebug(LogLevel.Debug); // formerly LogLevel.Verbose

        //your other stuff

    }
Run Code Online (Sandbox Code Playgroud)

  • 我想知道是否有一种方法只记录EF查询而没有其他任何东西. (2认同)

Eri*_*kEJ 7

您可以使用此代码登录控制台,我相信它将在以后更简单的api中包装:

using System;
using Microsoft.Data.Entity.Infrastructure;
using Microsoft.Data.Entity.Utilities;
using Microsoft.Framework.Logging;

public static class SqlCeDbContextExtensions
{
    public static void LogToConsole(this DbContext context)
    {
        var loggerFactory = ((IAccessor<IServiceProvider>)context).GetService<ILoggerFactory>();
        loggerFactory.AddProvider(new DbLoggerProvider());
    }
}
Run Code Online (Sandbox Code Playgroud)

DbLoggerProvider在这里实现:https://github.com/ErikEJ/EntityFramework7.SqlServerCompact/tree/master/src/Provider40/Extensions/Logging

  • 看起来EF团队只是改变了这一点:https://github.com/aspnet/EntityFramework/commit/dec9dc11abd462f6a8767b92111114a1fb295f6f (2认同)

mil*_*onb 5

如果您使用的是MS SQL Server,我过去使用的一种方法是使用SQL Server Profiler并捕获与 SQL Server 的所有交互,这捕获了提交的确切 SQL 并可以剪切并粘贴到SQL Server中Management Studio用于进一步审查/分析。我知道这并不能直接回答您关于实体框架的问题,但我发现这种通用方法对于任何语言/工具都非常有用。

一个技巧是在“跟踪属性”中设置新跟踪时,我发现在“事件选择”选项卡中调整事件的默认选择非常有用。大多数情况下,我会关闭审核登录/注销,除非专门跟踪此类问题。


Ran*_*dyB 5

由于EF位不断变化,我一直在努力解决上述所有问题,因此代码无法编译.截至今天(2016年2月19日)与EF7.0.0-rc1-final(预发布)和SQLite,这对我有用:

从EF7文档:

using System;
using System.IO;
using Microsoft.Extensions.Logging;

namespace EFLogging
{
    public class EFLoggerProvider : ILoggerProvider
    {
        public ILogger CreateLogger(string categoryName)
        {
            return new EFLogger();
        }

        public void Dispose()
        {
            // N/A
        }

        private class EFLogger : ILogger
        {
            public IDisposable BeginScopeImpl(object state)
            {
                return null;
            }

            public bool IsEnabled(LogLevel logLevel)
            {
                return true;
            }

            public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
            {
                File.AppendAllText(@".\EF.LOG", formatter(state, exception));
                Console.WriteLine(formatter(state, exception));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用上面的一些想法和EF7文档:

using System;
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Infrastructure;
using Microsoft.Extensions.DependencyInjection;  // Add this to EF7 docs code
using Microsoft.Extensions.Logging;

namespace DataAccessLayer
{
    public static class DbContextExtensions
    {
        public static void LogToConsole(this DbContext context)
        {
            var serviceProvider = context.GetInfrastructure<IServiceProvider>();
            var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
            loggerFactory.AddProvider(new EFLoggerProvider(logLevel));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:@ jnm2指出如果你添加"使用Microsoft.Extensions.DependencyInjection",EF7文档是正确的.谢谢!

最后,在我的App.OnStartup方法中:

using (var db = new MyDbContext())
{
    db.LogToConsole();
}
Run Code Online (Sandbox Code Playgroud)

此代码将创建一个日志文件,并将日志信息输出到Visual Studio输出窗口.我希望这会有所帮助 - 我肯定会在几周内再次发生变化.

  • GetInfrastructure <>()现在位于EF Core中的命名空间Microsoft.EntityFrameworkCore.Infrastructure中. (2认同)