网上这方面的资料很少,找到一个可以用的
http://code.msdn.microsoft.com/EFProviderWrappers
里面有dll可以下载,有教程,不过是E文的。
在Entity Framework中要查看到底最终转译的SQL command是甚麼相当困难,因為EF本身并没有提供像Linq2sql的Log属性来达成此点,这可能是因為Linq2sql比较单纯只对SQL Server,而EF在设计上是与资料库无关.
目前Entity Framework只能透过ObjectQuery的ToTraceString()来输出转译后的查询SQL语法.但对於SaveChange这类新增修改没有方式能够输出到底实际上的SQL command是甚麼.
以往要追踪的方式大概就是从SQL Profiler这类资料库附加的软体於资料库端追踪输出,但因為资料库通常不太可能单单只有一隻程式使用,在追踪上有点麻烦.
还好有人找出了解决之道并实作Library提供给大家使用.专案参考http://code.msdn.microsoft.com/EFProviderWrappers
他的做法是从EntityConnection着手,底下图的左边是原来的EF架构,而右边则使此Library的做法,中间多了一层Wrapping Provider.
再来介绍该如何使用此Library
1.请先至网站下载档案,因為下载下来為SourceCode所以请先用VS编译过.
2.编译后寻找EFTracingProvider目录底下的bindebug有两个dll,EFProviderWrapperToolkit.dll与EFTracingProvider.dll.
3.将这两个dll复製到你想要的目录.
4.开啟EF专案,使用加入参考方式加入此二个dll.
5.再来就是如何掛载Wrapping Provider,预设情况用EDM tool desinger设计好模型后,在VS中会產生.edmx与.designer.cs档案,而.designer.cs中会產生对应的ObjectContext class, 而ObjectContext class则是使用EDM tool desinger时所输入的名称,预设会是xxxEntities.
而掛载方式就是继承此class修改其建构式,譬如底下的范例是使用EDM建立一个TestEntities的ObjectContext. 新增一个class档案,命名為ExtendedTestEntities.cs修改如下,
public partial class ExtendedTestEntities : TestEntities
{
private TextWriter logOutput;
public ExtendedTestEntities()
: this("name=TestEntities")
{
}
public ExtendedTestEntities(string connectionString)
: base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(
connectionString,
"EFTracingProvider"
))
{
}
#region Tracing Extensions
private EFTracingConnection TracingConnection
{
get { return this.UnwrapConnection<EFTracingConnection>(); }
}
public event EventHandler<CommandExecutionEventArgs> CommandExecuting
{
add { this.TracingConnection.CommandExecuting += value; }
remove { this.TracingConnection.CommandExecuting -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFinished
{
add { this.TracingConnection.CommandFinished += value; }
remove { this.TracingConnection.CommandFinished -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFailed
{
add { this.TracingConnection.CommandFailed += value; }
remove { this.TracingConnection.CommandFailed -= value; }
}
private void AppendToLog(object sender, CommandExecutionEventArgs e)
{
if (this.logOutput != null)
{
this.logOutput.WriteLine(e.ToTraceString().TrimEnd());
this.logOutput.WriteLine();
}
}
public TextWriter Log
{
get { return this.logOutput; }
set
{
if ((this.logOutput != null) != (value != null))
{
if (value == null)
{
CommandExecuting -= AppendToLog;
}
else
{
CommandExecuting += AppendToLog;
}
}
this.logOutput = value;
}
}
#endregion
}
以上程式码若要套用於你的程式只要修改TestEntities相关描述即可,剩下的可以直接Copy.
最后在程式中使用方式如下
EFTracingProviderConfiguration.RegisterProvider();
using (ExtendedTestEntities context = new ExtendedTestEntities())
{
context.CommandExecuting += (sender, e) =>
{
string s = e.ToTraceString();
};
context.CommandFinished += (sender, e) =>
{
string s = e.ToTraceString();
};
...
}
透过CommandExecuting与CommandFinished事件则可拦截到最后EF下达SQL命令开始执行与执行后,另外还有执行失败的事件,而透过callback函式的参数之ToTraceString()即可取得完整的转译后之SQL command.
这边要注意一点,第一行的EFTracingProviderConfiguration.RegisterProvider();
是用来註册这个Library的Provider,因為这个Library除了Tracer SQL外还提供其他的功能,譬如说 Cache机制,都是透过Wrapping Provider来达成,如要了解可以参考官方网站之说明文件.
而除了在程式中使用,也可透过.net config机制来註册,在相关config中加入如下的描述即可
<system.data>
<DbProviderFactories>
<add name="EF Tracing Data Provider"
invariant="EFTracingProvider"
description="Tracing Provider Wrapper"
type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
<add name="EF Generic Provider Wrapper"
invariant="EFProviderWrapper"
description="Generic Provider Wrapper"
type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
</DbProviderFactories>
</system.data>