我可以看到实体框架为Visual Studio中的选择操作生成的SQL,但不能用于插入,更新和删除。如何在调试时看到Visual Studio中为“DataContext.SaveChanges”命令生成的SQL?
答案 0 :(得分:5)
如果你有visual studio ultimate,你可以在intellitrace中看到更新和插入。只需在调用SaveChanges后立即设置断点。
http://www.youtube.com/watch?v=fLBpZNXs-Lw
如果您在网络项目中使用它,您也可以使用迷你探查器。
答案 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,但该链接仍然适合为那些人提供指示!