在Visual Studio中查看为Entity Framework SaveChanges命令生成的SQL?

时间:2012-03-02 15:31:17

标签: visual-studio-2010 entity-framework linq-to-entities entity-framework-4.1

我可以看到实体框架为Visual Studio中的选择操作生成的SQL,但不能用于插入,更新和删除。如何在调试时看到Visual Studio中为“DataContext.SaveChanges”命令生成的SQL?

4 个答案:

答案 0 :(得分:5)

如果你有visual studio ultimate,你可以在intellitrace中看到更新和插入。只需在调用SaveChanges后立即设置断点。

http://www.youtube.com/watch?v=fLBpZNXs-Lw

如果您在网络项目中使用它,您也可以使用迷你探查器。

http://miniprofiler.com/

答案 1 :(得分:3)

我找到了一些非常简单的东西:

context.Database.Log = x => System.Diagnostics.Debug.WriteLine(x);

答案 2 :(得分:2)

在MSDN论坛上查看this thread;具体来说,由g_yordanov发布的帖子。他提供了一些代码,可以检索EF datacontext中所有更改的相应SQL语句。

作为免责声明,此代码涉及反映EF的内部结构,并可能在未来的版本中中断。但就目前而言,它在我们所有的EF应用程序中都能完美运行。

这是代码,仅供参考,以防链接消失。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data.Objects;
using System.Data.Common;
using System.Data.EntityClient;
using System.Collections;

namespace EntityExtensionMethods
{
    public static class CustomExtensions
    {
        private static readonly string entityAssemblyName =
            "system.data.entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

        public static string ToTraceString(this IQueryable query)
        {
            System.Reflection.MethodInfo toTraceStringMethod = query.GetType().GetMethod("ToTraceString");

            if (toTraceStringMethod != null)
                return toTraceStringMethod.Invoke(query, null).ToString();
            else
                return "";
        }

        public static string ToTraceString(this ObjectContext ctx)
        {
            Assembly entityAssemly = Assembly.Load(entityAssemblyName);

            Type updateTranslatorType = entityAssemly.GetType(
                "System.Data.Mapping.Update.Internal.UpdateTranslator");

            Type functionUpdateCommandType = entityAssemly.GetType(
                "System.Data.Mapping.Update.Internal.FunctionUpdateCommand");

            Type dynamicUpdateCommandType = entityAssemly.GetType(
                "System.Data.Mapping.Update.Internal.DynamicUpdateCommand");

            object[] ctorParams = new object[]
                        {
                            ctx.ObjectStateManager,
                            ((EntityConnection)ctx.Connection).GetMetadataWorkspace(),
                            (EntityConnection)ctx.Connection,
                            ctx.CommandTimeout
                        };

            object updateTranslator = Activator.CreateInstance(updateTranslatorType,
                BindingFlags.NonPublic | BindingFlags.Instance, null, ctorParams, null);

            MethodInfo produceCommandsMethod = updateTranslatorType
                .GetMethod("ProduceCommands", BindingFlags.Instance | BindingFlags.NonPublic);
            object updateCommands = produceCommandsMethod.Invoke(updateTranslator, null);

            List<DbCommand> dbCommands = new List<DbCommand>();

            foreach (object o in (IEnumerable)updateCommands)
            {
                if (functionUpdateCommandType.IsInstanceOfType(o))
                {
                    FieldInfo m_dbCommandField = functionUpdateCommandType.GetField(
                        "m_dbCommand", BindingFlags.Instance | BindingFlags.NonPublic);

                    dbCommands.Add((DbCommand)m_dbCommandField.GetValue(o));
                }
                else if (dynamicUpdateCommandType.IsInstanceOfType(o))
                {
                    MethodInfo createCommandMethod = dynamicUpdateCommandType.GetMethod(
                        "CreateCommand", BindingFlags.Instance | BindingFlags.NonPublic);

                    object[] methodParams = new object[]
                    {
                        updateTranslator,
                        new Dictionary<long, object>()
                    };

                    dbCommands.Add((DbCommand)createCommandMethod.Invoke(o, methodParams));
                }
                else
                {
                    throw new NotSupportedException("Unknown UpdateCommand Kind");
                }
            }


            StringBuilder traceString = new StringBuilder();
            foreach (DbCommand command in dbCommands)
            {
                traceString.AppendLine("=============== BEGIN COMMAND ===============");
                traceString.AppendLine();

                traceString.AppendLine(command.CommandText);
                foreach (DbParameter param in command.Parameters)
                {
                    traceString.AppendFormat("{0} = {1}", param.ParameterName, param.Value);
                    traceString.AppendLine();
                }

                traceString.AppendLine();
                traceString.AppendLine("=============== END COMMAND ===============");
            }

            return traceString.ToString();
        }
    }
}

答案 3 :(得分:-2)

我知道这已经过时了,但这是我搜索中出现的第一个链接,所以我认为我发布的最简单的解决方案是使用SQL Profiler:

String or binary data would be truncated.The statement has been terminated

Ooops ...只是看到OP无法访问Profiler,但该链接仍然适合为那些人提供指示!