使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句

Posted 吴晓阳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句相关的知识,希望对你有一定的参考价值。

开始

EF6.1也出来不少日子了,6.1相比6.0有个很大的特点就是新增了System.Data.Entity.Infrastructure.Interception 命名空间,此命名空间下的对象可以允许我们更加方便的了解到EF运行时的一些信息,当然我们最想看的还是EF生成的Sql语句,话不多讲,开始干吧;

01.class EFIntercepterLogging : DbCommandInterceptor
02.{
03.private readonly Stopwatch _stopwatch = new Stopwatch();
04.public override void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
05.{
06.base.ScalarExecuting(command, interceptionContext);
07._stopwatch.Restart();
08.}
09.public override void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
10.{
11._stopwatch.Stop();
12.if (interceptionContext.Exception != null)
13.{
14.Trace.TraceError("Exception:{1} \r\n --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString());
15.}
16.else
17.{
18.Trace.TraceInformation("\r\n执行时间:{0} 毫秒\r\n-->ScalarExecuted.Command:{1}\r\n", _stopwatch.ElapsedMilliseconds, command.CommandText);
19.}
20.base.ScalarExecuted(command, interceptionContext);
21.}
22.public override void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
23.{
24.base.NonQueryExecuting(command, interceptionContext);
25._stopwatch.Restart();
26.}
27.public override void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
28.{
29._stopwatch.Stop();
30.if (interceptionContext.Exception != null)
31.{
32.Trace.TraceError("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString());
33.}
34.else
35.{
36.Trace.TraceInformation("\r\n执行时间:{0} 毫秒\r\n-->NonQueryExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
37.}
38.base.NonQueryExecuted(command, interceptionContext);
39.}
40.public override void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
41.{
42.base.ReaderExecuting(command, interceptionContext);
43._stopwatch.Restart();
44.}
45.public override void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
46.{
47._stopwatch.Stop();
48.if (interceptionContext.Exception != null)
49.{
50.Trace.TraceError("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString());
51.}
52.else
53.{
54.Trace.TraceInformation("\r\n执行时间:{0} 毫秒 \r\n -->ReaderExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
55.}
56.base.ReaderExecuted(command, interceptionContext);
57.}
58.}

上面这段代码需要命名空间:

using System.Data.Entity.Infrastructure.Interception;
using System.Diagnostics;

从方法名我们可以看出大致就三类:读取类的sql,[Reader],非读取类的sql,[NonQuery],还有[Scalar],这类用的比较少,跟原始的ADO.NET命令类型基本一样,不多讲.每个sql语句类型的方法都有执行前Executing,执行后Executed,从命名上我们就可以看出AOP的身影哈,接下来看如何使用它...

技术分享

嗯,对没错,就是这么简单,当然你还可以把红线里那句代码放在Global文件里.

我们看看运行效果

技术分享


技术分享

个人感觉是比用什么插件,第三方类库,SqlProfile什么的方便点点,用博客园的Google搜索了一下,貌似没发现其他园友写这个方法,可能是太简单了,都不愿意写,还是麻烦推荐一下让更多的园友看到!

以上是关于使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句的主要内容,如果未能解决你的问题,请参考以下文章

首先使用 Entity Framework 6 代码访问 Oracle Synonyms

在 Entity Framework 6.1(非核心)中,如何使用 IndexAttribute 来定义聚集索引?

小知识

MongoDB努力更新数据库

如何在桌面应用程序中使用 DbContext 和 DI?

如何在 .NET 中使用 Dapper 处理数据库连接?