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

时间:2014-11-05 00:40:59

标签: entity-framework entity-framework-core

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

我正在编写一个简单的控制台程序,我尝试使用EF6使用的same logging technic,但实体框架7上没有DbContext.Database.Log。有没有办法记录或只是采取看一下EF7生成的SQL?

10 个答案:

答案 0 :(得分:8)

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

Startup.cs 中,您可以使用包含大量配置的Configure方法。它应该如下所示(除了你的东西)。

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

        //your other stuff

    }

答案 1 :(得分: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());
    }
}

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

答案 2 :(得分: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));
            }
        }
    }
}

使用上面的一些想法和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));
        }
    }
}

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

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

using (var db = new MyDbContext())
{
    db.LogToConsole();
}

此代码将创建一个日志文件,并将日志信息输出到Visual Studio输出窗口。我希望这会有所帮助 - 我确信在几周后,这些内容会再次改变。

答案 3 :(得分:4)

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

设置新跟踪时,一个提示位于跟踪属性中,我发现在“事件选择”选项卡中调整事件的默认选择很有用。除非专门跟踪此类问题,否则我主要关闭审核登录/注销。

答案 4 :(得分:4)

使用最新版本的EF7-beta8,安东尼的答案需要稍微调整一下。这就是我为了让它发挥作用所做的一切。

internal static class DbContextExtensions
{
    public static void LogToConsole(this DbContext context)
    {
        var loggerFactory = context.GetService<ILoggerFactory>();
        loggerFactory.AddConsole(LogLevel.Verbose);
    }
}

答案 5 :(得分:3)

我想我想出来了。使用当前的EF7位,ILoggerFactory在EF正在使用的依赖注入容器中注册。当它被转换为IDbContextServices时,您可以通过DbContext的ScopedServiceProvider属性获取对容器的引用,该容器是一个IServiceProvider。从那里,您可以使用Microsoft.Framework.Logging.Console NuGet包中的AddToConsole扩展方法获取ILoggerFactory并对其进行配置。

public static void LogToConsole(this DbContext context)
{
    // IServiceProvider represents registered DI container
    IServiceProvider contextServices = ((IDbContextServices)context).ScopedServiceProvider;

    // Get the registered ILoggerFactory from the DI container
    var loggerFactory = contextServices.GetRequiredService<ILoggerFactory>();

    // Add a logging provider with a console trace listener
    loggerFactory.AddConsole(LogLevel.Verbose);
}

以下是我为此代码段创建的要点:https://gist.github.com/tonysneed/4cac4f4dae2b22e45ec4

答案 6 :(得分:2)

这适用于EF7 rc2-16485:

"EntityFramework.MicrosoftSqlServer": "7.0.0-rc2-16485",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc2-15888",

public static class DbContextExtensions
{
    public static void LogToConsole(this DbContext context)
    {
        var contextServices = ((IInfrastructure<IServiceProvider>) context).Instance;
        var loggerFactory = contextServices.GetRequiredService<ILoggerFactory>();
        loggerFactory.AddConsole(LogLevel.Verbose);
    }
}

答案 7 :(得分:2)

使用ASP.NET Core 2.0 you get SQL logging automatically。无需做任何额外的事情。

答案 8 :(得分:1)

作为上述答案的替代方案,我发现this answer是迄今为止最容易解释的解决方案:

private readonly ILoggerFactory loggerFactory;

// Using dependency injection
public FooContext(ILoggerFactory loggerFactor) {
    this.loggerFactory = loggerFactory;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
    optionsBuilder.UseLoggerFactory(loggerFactory);    // Register logger in context
}

答案 9 :(得分:0)

对于只希望记录SQL查询(使用Entity Framework Core和.NET Core 2.0或更高版本)的用户,在DbContext类中使用以下代码:

public static readonly LoggerFactory MyLoggerFactory
    = new LoggerFactory(new[]
    {
        new ConsoleLoggerProvider((category, level)
            => category == DbLoggerCategory.Database.Command.Name
               && level == LogLevel.Information, true)
    });

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLoggerFactory(MyLoggerFactory) // Warning: Do not create a new ILoggerFactory instance each time
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True;ConnectRetryCount=0");

参考:https://docs.microsoft.com/en-us/ef/core/miscellaneous/logging