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


624

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

(在我特殊的情况下,我正在使用mysql提供程序-如果重要的话)


1
来自MSDN杂志的这篇文章介绍了Entity Framework 4的某些分析选项
Arve

2
链接的“重复”问题是针对LINQ to SQL的,因此实际上不是重复。
jrummell 2011年

2
在调试器下运行时,IntelliTrace会显示已执行的SQL查询,尽管没有查询结果。
ivan_pozdeev 2014年

如果您对在开发过程中看到SQL感兴趣,可以使用LINQPad。在结果中运行LINQ查询时,将有一个SQL选项卡,其中显示了已执行的SQL语句。对于mySQL,您必须安装驱动程序。我没有可用的mySQL数据库,但它应该可以工作。
gligoran 2015年

Answers:


472

您可以执行以下操作:

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。


20
这样,对于以.Single()、. Count()、. Any()等结尾的查询,您将不会获得SQL。
springy76

24
那是因为运行.Single()对象之后,IQueryable我猜想已经没有了。
Suhas 2013年

11
使用EF6,我只能通过反射获得它。但首先,我不得不转换resultSystem.Data.Entity.Infrastructure.DbQuery<T>,然后获取内部属性InternalQuery(System.Data.Entity.Internal.Linq.InternalQuery<T>),然后才使用ToTraceString()
itsho 2014年

9
添加对以上dll中存在的System.Data.Entity,System.Data.Objects.ObjectQuery的引用
Mahesh,2014年

54
在EF6中,您可以做result.ToString()
Scott Chamberlain

955

对于使用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/

注意:确保以调试模式运行项目。


107
这个答案值得更多的爱(如果您使用的是EF6 +)-很棒的调试添加,只需将其添加到DBContext构造函数中(this.Database.Log = ...)
keithl8041 2014年

21
确保在调试模式下运行项目,检查“输出”窗格的组合框中是否选中了“调试”项,还检查调试是否未重定向到“即时”(“工具”>“选项”>“调试”>“将所有“输出窗口”文本重定向到“即时”)窗口)
rkawano 2014年

5
有没有办法让它直接将变量值包含在生成的sql中?大一点的人有点痛苦。
克里斯(Chris

22
@Matt Nibecker这在EF Core中不起作用。EF Core的替代方案是什么?

9
警告:我实现此操作的目的是仅在开发中运行它。当我们部署到测试环境时,我们开始突然看到IIS Worker进程中的内存泄漏。进行内存分析后,我们意识到,即使显式GC也不再收集实体上下文对象(是的,它们在using语句中)。删除此行使所有操作恢复正常。因此,尽管这是一个很棒的工具,但请确保仅将其构建到应用程序中进行开发。
布兰登·巴克利

82

从EF6.1开始,您可以使用拦截器来注册数据库记录器。请参见此处的 “拦截器”和“记录数据库操作”一章

<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>

1
关于主题的博客文章blog.oneunicorn.com/2014/02/09/…–
Tim Abell

12
精确度如下:<configuration> <entityFramework> <interceptors> ... </ interceptors> </ entityFramework> </ configuration>
Christophe P

80

如果使用的是DbContext,则可以执行以下操作来获取SQL:

var result = from i in myContext.appEntities
             select new Model
             {
                 field = i.stuff,
             };
var sql = result.ToString();

12
ToString()将为您提供带有变量的查询,例如p__linq__0,而不是最终值(例如:34563代替p__linq__0
sports

24

适用于EF 6.0及更高版本:对于那些想了解更多有关日志记录功能并添加一些已经给出的答案的人。

现在可以记录从EF发送到数据库的任何命令。要查看从EF 6.x生成的查询,请使用DBContext.Database.Log property

记录什么

 - 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

要登录到外部文件:

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();
   }
}

此处更多信息:记录和拦截数据库操作


21

您可以在EF 4.1中执行以下操作:

var result = from x in appEntities
             where x.id = 32
             select x;

System.Diagnostics.Trace.WriteLine(result .ToString());

这将为您提供生成的SQL。


1
实际上,我认为这仅在查询返回匿名类型时有效。如果返回自定义类型,则ToString()输出为该自定义类型的名称空间。例如,如果上面的代码是select new CustomType { x = x.Name },则返回的值将类似于Company.Models.CustomType而不是所生成的SQL。
乍得利维

8
这种技术System.Data.Objects.ObjectQuery``1[MyProject.Models.Product]为我产生了。
卡尔·G

1
@CarlG System.Data.Objects.ObjectQuery不是EF 4.1(DbContext)。使用DbContext,它将是System.Data.Entity.Infrastructure.DbQuery`1 [MyProject.Models.Product],它的确在调用“ ToString()”时输出了它的SQL
springy76 2013年

这将为您提供在输出窗口中的何处生成的SQL?下拉菜单中的哪个选项?
JsonStatham

17

我的答案针对EF 核心。我引用了这个github问题,以及有关配置DbContext的文档:

简单

覆盖此处所示的类()的OnConfiguring方法,以使用ConsoleLoggerProvider;您的查询应登录到控制台:DbContextYourCustomDbContext

public class YourCustomDbContext : DbContext
{
    #region DefineLoggerFactory
    public static readonly LoggerFactory MyLoggerFactory
        = new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
    #endregion


    #region RegisterLoggerFactory
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseLoggerFactory(MyLoggerFactory); // Warning: Do not create a new ILoggerFactory instance each time                
    #endregion
}

复杂

这种复杂的情况下,避免了重写DbContext OnConfiguring方法。,在文档中不建议这样做:“除非测试针对整个数据库,否则这种方法不适合进行测试。”

此复杂案例使用:

  • IServiceCollectionStartupConfigureServices的方法(而不是重写OnConfiguring方法;所述益处是之间的松耦合DbContextILoggerProvider要使用)
  • 的实现ILoggerProvider(而不是使用ConsoleLoggerProvider上面显示的实现;好处是我们的实现说明了如何记录到文件(我没有看到EF Core附带文件记录提供程序))

像这样:

public class Startup

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        var lf = new LoggerFactory();
        lf.AddProvider(new MyLoggerProvider());

        services.AddDbContext<YOUR_DB_CONTEXT>(optionsBuilder => optionsBuilder
                .UseSqlServer(connection_string)
                //Using the LoggerFactory 
                .UseLoggerFactory(lf));
        ...
    }
}

这是的实现MyLoggerProvider(其实MyLogger现将其日志附加到您可以配置的文件中;您的EF Core查询将出现在文件中。)

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;
        }
    } 
}

所以...没有初学者的方法呢?
Juan De la Cruz

1
@JuanDelaCruz我简化了答案;尝试简单的替代方法
红豌豆

16

有两种方法:

  1. 要查看将要生成的SQL,只需调用ToTraceString()。您可以将其添加到监视窗口中并设置断点,以查看任何LINQ查询在任何给定点的查询。
  2. 您可以将跟踪器附加到所选的SQL Server,这将向您显示最终查询的所有详细信息。对于MySQL,跟踪查询的最简单方法是在尾部添加查询日志tail -f。您可以在官方文档中了解有关MySQL的日志记录功能的更多信息。对于SQL Server,最简单的方法是使用附带的SQL Server Profiler。

27
ToTraceString是什么?

正如尼克在我发布回应后立即指出的那样,该ObjectQuery。
本杰明·波拉克

2
SQL Server Profiler捕获前4000个字符,但是EF查询的长度可能更长。

7

为了使查询始终很方便,而无需更改代码,请将其添加到DbContext并在Visual Studio的输出窗口中进行检查。

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.Log = (query)=> Debug.Write(query);
    }

与@Matt Nibecker答案类似,但是您不必每次都需要在查询中将其添加到当前代码中。


最好的答案!
AlexSC '19

7

SQL Management Studio =>工具=> SQL Server分析器

文件=>新建跟踪...

使用模板=>空白

事件选择=> T-SQL

左侧检查:SP.StmtComplete

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

开始运行该概要文件,然后触发查询。

单击此处获取源信息


1
抱歉,这仅适用于SQL Server,不适用于MySQL
Andrew pate


5
IQueryable query = from x in appEntities
                   where x.id = 32
                   select x;
var queryString = query.ToString();

将返回sql查询。使用EntityFramework 6的数据上下文进行工作


4
我刚刚尝试过,它可以找出对象:Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1 [System.Linq.IGrouping,2[System.Int32,String]]而不是实际的查询。我错过了什么吗?还是您忘了提些什么?
loganjones16

5

我正在做集成测试,并且需要它来调试Entity Framework Core 2.1中生成的SQL语句,因此我使用DebugLoggerProviderConsoleLoggerProvider类似这样:

[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控制台的示例输出:

示例SQL语句输出


1
DebugLoggerPrivider和ConsoleLoggerProvider似乎只存在于.NET的核心:docs.microsoft.com/en-us/dotnet/api/...
加布里埃尔马加纳

4

死灵法师。
搜索任何.NET Framework解决方案时,此页面是第一个搜索结果,因此,作为一项公共服务,这是在EntityFramework Core(适用于.NET Core 1和2)中的完成方式:

var someQuery = (
    from projects in _context.projects
    join issues in _context.issues on projects.Id equals issues.ProjectId into tmpMapp
    from issues in tmpMapp.DefaultIfEmpty()
    select issues
) //.ToList()
;

// string sql = someQuery.ToString();
// string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions.ToSql(someQuery);
// string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions1.ToSql(someQuery);
// using Microsoft.EntityFrameworkCore;
string sql = someQuery.ToSql();
System.Console.WriteLine(sql);

然后是这些扩展方法(.NET Core 1.0的IQueryableExtensions1,.NET Core 2.0的IQueryableExtensions):

using System;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Remotion.Linq.Parsing.Structure;


namespace Microsoft.EntityFrameworkCore
{

    // /programming/1412863/how-do-i-view-the-sql-generated-by-the-entity-framework
    // http://rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/

    public static class IQueryableExtensions
    {
        private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();

        private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields
            .First(x => x.Name == "_queryCompiler");

        private static readonly PropertyInfo NodeTypeProviderField =
            QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider");

        private static readonly MethodInfo CreateQueryParserMethod =
            QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser");

        private static readonly FieldInfo DataBaseField =
            QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");

        private static readonly PropertyInfo DatabaseDependenciesField =
            typeof(Database).GetTypeInfo().DeclaredProperties.Single(x => x.Name == "Dependencies");

        public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
        {
            if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>))
            {
                throw new ArgumentException("Invalid query");
            }

            var queryCompiler = (QueryCompiler) QueryCompilerField.GetValue(query.Provider);
            var nodeTypeProvider = (INodeTypeProvider) NodeTypeProviderField.GetValue(queryCompiler);
            var parser = (IQueryParser) CreateQueryParserMethod.Invoke(queryCompiler, new object[] {nodeTypeProvider});
            var queryModel = parser.GetParsedQuery(query.Expression);
            var database = DataBaseField.GetValue(queryCompiler);
            var databaseDependencies = (DatabaseDependencies) DatabaseDependenciesField.GetValue(database);
            var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false);
            var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
            modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
            var sql = modelVisitor.Queries.First().ToString();

            return sql;
        }
    }



    public class IQueryableExtensions1
    {
        private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();

        private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo()
            .DeclaredFields
            .First(x => x.Name == "_queryCompiler");

        private static readonly PropertyInfo NodeTypeProviderField =
            QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider");

        private static readonly MethodInfo CreateQueryParserMethod =
            QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser");

        private static readonly FieldInfo DataBaseField =
            QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");

        private static readonly FieldInfo QueryCompilationContextFactoryField = typeof(Database).GetTypeInfo()
            .DeclaredFields.Single(x => x.Name == "_queryCompilationContextFactory");


        public static string ToSql<TEntity>(IQueryable<TEntity> query) where TEntity : class
        {
            if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>))
            {
                throw new ArgumentException("Invalid query");
            }

            var queryCompiler = (IQueryCompiler) QueryCompilerField.GetValue(query.Provider);

            var nodeTypeProvider = (INodeTypeProvider) NodeTypeProviderField.GetValue(queryCompiler);
            var parser =
                (IQueryParser) CreateQueryParserMethod.Invoke(queryCompiler, new object[] {nodeTypeProvider});
            var queryModel = parser.GetParsedQuery(query.Expression);
            var database = DataBaseField.GetValue(queryCompiler);
            var queryCompilationContextFactory =
                (IQueryCompilationContextFactory) QueryCompilationContextFactoryField.GetValue(database);
            var queryCompilationContext = queryCompilationContextFactory.Create(false);
            var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
            modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
            var sql = modelVisitor.Queries.First().ToString();

            return sql;
        }


    }


}

我正在使用EF Core 2.0.1,上述建议的结果是:System.InvalidCastException:“无法将类型为Microsoft.EntityFrameworkCore.Query.Internal.InMemoryQueryModelVisitor的对象强制转换为类型为“ Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor”线路: var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
克里斯·沃尔夫

2
@ChrisWolf如果您遵循原始作者的要旨,则可以找到提供该扩展方法更新版本的人。为我工作。
B12Toaster

2

就我而言,对于EF 6+,不是在“即时窗口”中使用它来查找查询字符串:

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。


2

我已经做到了:

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

是的,但是我相信没人愿意看到p__linq__i,而是真正的价值
Tom Stickel

这种方法在EF 6中仍然有效,如果您只关心查询结构是什么样的,它将很有帮助。在我的情况下,我创建IQueryable <T>对象的项目没有对System.Data.Entity的引用,也不想添加它仅用于调试目的。所以这种方法很好用。
wctiger



1

虽然这里有很好的答案,但没有解决我的完全的问题(我希望得到整个SQL语句,包括参数,从的DbContext任何IQueryable的。下面的代码就是这样做的,这是从谷歌代码片段的组合。 我仅使用EF6 +进行了测试

顺便说一句,这个任务花了我比我想象的更长的时间。恕我直言,实体框架中的抽象有点多。

首先使用。您将需要对“ System.Data.Entity.dll”的明确引用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data.Common;
using System.Data.Entity.Core.Objects;
using System.Data.Entity;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Reflection;

下列类将IQueryable转换为DataTable。根据需要进行修改:

public class EntityFrameworkCommand
{
    DbContext Context;

    string SQL;

    ObjectParameter[] Parameters;

    public EntityFrameworkCommand Initialize<T>(DbContext context, IQueryable<T> query)
    {
        Context = context;
        var dbQuery = query as DbQuery<T>;
        // get the IInternalQuery internal variable from the DbQuery object
        var iqProp = dbQuery.GetType().GetProperty("InternalQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        var iq = iqProp.GetValue(dbQuery, null);
        // get the ObjectQuery internal variable from the IInternalQuery object
        var oqProp = iq.GetType().GetProperty("ObjectQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        var objectQuery = oqProp.GetValue(iq, null) as ObjectQuery<T>;
        SQL = objectQuery.ToTraceString();
        Parameters = objectQuery.Parameters.ToArray();
        return this;
    }

    public DataTable GetData()
    {
        DataTable dt = new DataTable();
        var connection = Context.Database.Connection;
        var state = connection.State;
        if (!(state == ConnectionState.Open))
            connection.Open();
        using (var cmd = connection.CreateCommand())
        {
            cmd.CommandText = SQL;
            cmd.Parameters.AddRange(Parameters.Select(p => new SqlParameter("@" + p.Name, p.Value)).ToArray());
            using (var da = DbProviderFactories.GetFactory(connection).CreateDataAdapter())
            {
                da.SelectCommand = cmd;
                da.Fill(dt);
            }
        }
        if (!(state == ConnectionState.Open))
            connection.Close();
        return dt;
    }
}

要使用,只需按以下方式调用它:

var context = new MyContext();
var data = ....//Query, return type can be anonymous
    .AsQueryable();
var dt = new EntityFrameworkCommand()
    .Initialize(context, data)
    .GetData();

0

实体框架4解决方案

这里的大多数答案都是EF6特定的。对于那些仍在使用EF4的人来说,这是一个。

此方法代替了@p__linq__0/ etc。参数及其实际值,因此您只需将输出复制并粘贴到SSMS中即可运行或调试它。

    /// <summary>
    /// Temporary debug function that spits out the actual SQL query LINQ is generating (with parameters)
    /// </summary>
    /// <param name="q">IQueryable object</param>
    private string Debug_GetSQLFromIQueryable<T>(IQueryable<T> q)
    {
        System.Data.Objects.ObjectQuery oq = (System.Data.Objects.ObjectQuery)q;
        var result = oq.ToTraceString();
        List<string> paramNames = new List<string>();
        List<string> paramVals = new List<string>();
        foreach (var parameter in oq.Parameters)
        {
            paramNames.Add(parameter.Name);
            paramVals.Add(parameter.Value == null ? "NULL" : ("'" + parameter.Value.ToString() + "'"));
        }
        //replace params in reverse order, otherwise @p__linq__1 incorrectly replaces @p__linq__10 for instance
        for (var i = paramNames.Count - 1; i >= 0; i--)
        {
            result = result.Replace("@" + paramNames[i], paramVals[i]);
        }
        return result;
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.