如何查看entity framework生成的SQL?
我如何查看由entity framework生成的SQL?
(在我个人的情况下,我使用mysql提供程序 – 如果它很重要)
您可以执行以下操作:
IQueryable query = from x in appEntities where x.id = 32 select x; var sql = ((System.Data.Objects.ObjectQuery)query).ToTraceString();
或在EF6中:
var sql = ((System.Data.Entity.Core.Objects.ObjectQuery)query) .ToTraceString();
这会给你生成的SQL。
对于那些使用Entity Framework 6以上的人来说,如果你想在Visual Studio中查看输出SQL(就像我做的那样),你必须使用新的日志/拦截function。
添加以下代码行将在Visual Studio输出面板中吐出生成的SQL(以及其他与执行相关的详细信息):
using (MyDatabaseEntities context = new MyDatabaseEntities()) { context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s); // query the database using EF here. }
有关在这个漂亮的博客系列中loginEF6的更多信息: http : //blog.oneunicorn.com/2013/05/08/ef6-sql-logging-part-1-simple-logging/
注意:确保你在DEBUG模式下运行你的项目。
如果您使用的是DbContext,则可以执行以下操作来获取SQL:
var result = from i in myContext.appEntities select new Model { field = i.stuff, }; var sql = result.ToString();
从EF6.1开始,您可以使用拦截器来注册数据库logging器。 请参阅“拦截器”和“logging数据库操作”的章节
<interceptors> <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework"> <parameters> <parameter value="C:\Temp\LogOutput.txt"/> <parameter value="true" type="System.Boolean"/> </parameters> </interceptor> </interceptors>
有两种方法:
- 要查看将要生成的SQL,只需调用
ToTraceString()
。 您可以将它添加到您的观察窗口中,并设置一个断点,以查看任何LINQ查询在任何给定点上的查询。 - 你可以附加一个跟踪器到你select的SQL服务器,它会显示你所有的血腥细节的最终查询。 在MySQL的情况下,跟踪查询最简单的方法就是简单地用
tail -f
尾部查询日志。 您可以在官方文档中了解有关MySQL日志loggingfunction的更多信息。 对于SQL Server,最简单的方法是使用包含的SQL Server分析器。
您可以在EF 4.1中执行以下操作:
var result = from x in appEntities where x.id = 32 select x; System.Diagnostics.Trace.WriteLine(result .ToString());
这会给你生成的SQL。
适用于EF 6.0或更高版本:对于那些想要了解更多关于日志loggingfunction以及添加已经给出的一些答案的人。
现在可以logging从EF发送到数据库的任何命令。 要从EF 6.x查看生成的查询,请使用DBContext.Database.Log property
什么logging
- 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.
例:
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(); }
输出:
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
login到外部文件:
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(); } }
更多信息: 日志和截取数据库操作
那么,我现在正在使用Express分析器,缺点是它只适用于MS SQL Server。 你可以在这里find这个工具: https : //expressprofiler.codeplex.com/
IQueryable query = from x in appEntities where x.id = 32 select x; var queryString = query.ToString();
将返回的SQL查询。 使用EntityFramework的datacontext工作6
为了让查询总是方便的,不用修改代码,将它添加到DbContext中,并在Visual Studio的输出窗口中进行检查。
protected override void OnModelCreating(DbModelBuilder modelBuilder) { Database.Log = (query)=> Debug.Write(query); }
类似于@Matt Nibecker的回答,但是用这个你不必在当前代码中添加它,每次你需要查询。
在我的情况下EF 6+,而不是在即时窗口中使用此查找查询string:
var sql = ((System.Data.Entity.Core.Objects.ObjectQuery)query).ToTraceString();
我最终不得不使用这个来获得生成的SQL命令:
var sql = ((System.Data.Entity.Infrastructure.DbQuery<<>f__AnonymousType3<string,string,string,short,string>>)query).ToString();
当然你的匿名签名可能会有所不同。
HTH。
我刚刚做了这个:
IQueryable<Product> query = EntitySet.Where(p => p.Id == id); Debug.WriteLine(query);
输出结果如下:
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
对于我来说,使用EF6和Visual Studio 2015,我在即时窗口中input了query
,它给了我生成的SQL语句
如果你想拥有参数值(不仅@p_linq_0
而且还有它们的值),你可以使用IDbCommandInterceptor
并添加一些日志到ReaderExecuted
方法。
我的回答解决了EF 核心问题 (正如一些评论人员在最高评分答案“什么是EF核心替代scheme?”中所述)
从这个github的问题引用的文档 :
当configuration你的DbContext时,你告诉DbContextOptionsBuilder.UseLoggerFactory
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var lf = new LoggerFactory(); lf.AddProvider(new MyLoggerProvider()); optionsBuilder.UseLoggerFactory(lf); }
LoggerFactory
有两个选项:
-
自己实例化新的
LoggerFactory()
,添加自己的Provider。 在上面的示例MyLoggerProvider
,请参阅该类定义的链接 ) -
您的代码可能有权访问dependency injection的
ILoggerFactory
。 在我的情况下,我使用AddDbContext
,在Configure()
。 在Configure()
这一点上,在范围中没有dependency injection的ILoggerFactory
,所以我不能使用这种技术。
这里是MyLoggerProvider
的实现(来自第一种技术):
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; } } }