Entity framework 如何使用Entity Framework 7记录查询?
我在夜间构建频道上使用EntityFramework 7(现在我使用的是EntityFramework.7.0.0-beta2-11524版本),我正试图记录EF出于好奇而生成的查询Entity framework 如何使用Entity Framework 7记录查询?,entity-framework,entity-framework-core,Entity Framework,Entity Framework Core,我在夜间构建频道上使用EntityFramework 7(现在我使用的是EntityFramework.7.0.0-beta2-11524版本),我正试图记录EF出于好奇而生成的查询 我正在编写一个简单的控制台程序,我尝试使用EF6使用的,但是在EntityFramework7上不能使用DbContext.Database.Log。是否有办法记录或查看EF7生成的SQL?如果您使用的是MS SQL Server,我过去使用的一种方法是使用SQL Server Profiler并捕获与SQL Se
我正在编写一个简单的控制台程序,我尝试使用EF6使用的,但是在EntityFramework7上不能使用
DbContext.Database.Log
。是否有办法记录或查看EF7生成的SQL?如果您使用的是MS SQL Server,我过去使用的一种方法是使用SQL Server Profiler并捕获与SQL Server的所有交互,这将捕获提交的确切SQL,并可剪切粘贴到SQL Server Management Studio中以供进一步查看/分析。
我知道这并不能直接回答您关于实体框架的问题,但我发现这种通用方法对于任何语言/工具都非常有用
设置新跟踪时,跟踪属性中有一个提示,我发现在“事件选择”选项卡中调整事件的默认选择非常有用。大多数情况下,我会关闭审核登录/注销,除非专门跟踪此类问题。您可以使用此代码登录到控制台,我相信稍后它将封装在一个更简单的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());
}
}
使用系统;
使用Microsoft.Data.Entity.Infrastructure;
使用Microsoft.Data.Entity.Utilities;
使用Microsoft.Framework.Logging;
公共静态类SqlCeDbContextExtensions
{
公共静态void LogToConsole(此DbContext上下文)
{
var loggerFactory=((IAccessor)context.GetService();
AddProvider(新的DbLoggerProvider());
}
}
DbLoggerProvider在这里实现:我想我已经解决了这个问题。使用当前的EF7位,iLogger工厂在EF使用的依赖项注入容器中注册。当容器强制转换为IDbContextServices时,您可以通过DbContext的ScopedServiceProvider属性获取对容器(IServiceProvider)的引用。从那里,您可以获取iLogger工厂,并使用Microsoft.Framework.Logging.Console NuGet包中的AddToConsole扩展方法对其进行配置
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);
}
publicstaticvoidlogtoconsole(此DbContext上下文)
{
//IServiceProvider表示已注册的DI容器
IServiceProvider contextServices=((IDbContextServices)上下文);
//从DI容器获取已注册的iLogger工厂
var loggerFactory=contextServices.GetRequiredService();
//添加带有控制台跟踪侦听器的日志提供程序
AddConsole(LogLevel.Verbose);
}
以下是我为这段代码创建的要点:对于最新版本的EF7-beta8,Anthony的答案需要稍加修改。这是我为让它工作所做的
internal static class DbContextExtensions
{
public static void LogToConsole(this DbContext context)
{
var loggerFactory = context.GetService<ILoggerFactory>();
loggerFactory.AddConsole(LogLevel.Verbose);
}
}
内部静态类DbContextensions
{
公共静态void LogToConsole(此DbContext上下文)
{
var loggerFactory=context.GetService();
AddConsole(LogLevel.Verbose);
}
}
对于那些使用EF7的人来说,以上这些都不适合我。但我就是这样让它工作的。(摘自@avi cherry的评论)
在Startup.cs中,您可能有一个配置方法,其中包含一系列配置。它应该如下所示(除了你的东西)
这在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);
}
}
“EntityFramework.MicrosoftSqlServer”:“7.0.0-rc2-16485”,
“Microsoft.Extensions.Logging.Console”:“1.0.0-rc2-15888”,
公共静态类DbContextensions
{
公共静态void LogToConsole(此DbContext上下文)
{
var contextServices=((IInfrastructure)context).Instance;
var loggerFactory=contextServices.GetRequiredService();
AddConsole(LogLevel.Verbose);
}
}
由于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));
}
}
}
}
此代码将创建一个日志文件,并将日志信息输出到VisualStudio输出窗口。我希望这能有所帮助——我相信几周后,bits将再次改变。作为上述答案的替代方案,我找到了迄今为止最简单的解决方案:
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
}
使用ASP.NET Core 2.0。无需执行任何额外操作。对于那些只希望记录SQL查询的人(使用Entity Framework Core with.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");
参考资料:看起来EF团队又改变了这一点:有人找到了使用当前EF7位登录控制台的方法吗?您在哪里添加了这个?似乎不再有效。实际上,您可以在Startup.cs中向“Configure”方法添加一个ILogger工厂参数,并在那里调用.AddConsole()。虽然存在接受ILogger工厂参数的配置重载,但Startup.cs仅适用于web应用程序,而不适用于控制台应用程序。:)但是,web应用程序将受益于将SQL记录到“调试输出”窗口。我想知道是否有办法只记录EF查询而不记录其他内容。@MahmoudAli EF Core文档说明了如何对某些日志类别进行筛选:文档实际上是正确的,但您需要使用Microsoft.Extensions.DependencyInjection代码>。我遇到了同样的事情。啊哈!更新了我的帖子。谢谢谢谢你的更新!我需要看看RC2 bits中有什么新功能。GetInfrastructure()现在位于命名空间Microsoft.EntityFrameworkCore.Infrastructure中的EF Core.yack中。这是一种方式,太多的代码只获取输出的sql。如果您现在有问题并且没有时间构建和部署,这是一个非常实用的答案:)此外,您还可以将粘贴查询从sql Profiler复制到sql Management Studio中,以进一步诊断错误。
using (var db = new MyDbContext())
{
db.LogToConsole();
}
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
}
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");