EF监听生成的所有sql语句(包括插入,删除sql)

  • Post author:
  • Post category:其他


1、前言:用linq配合ef做数据相关操作时,如果我们想得到所生成的sql,大概可以像这样。

(1)用.ToTraceString(),当然你要把先把查询语句的类型转成ObjectQuery<T>类型。


var query


=


from s


in


context.Students



where


s.Name


==







张三






select s;

ObjectQuery


<



Student



>


studentsQuery


=


query


as


ObjectQuery


<



Student



>


;





string


sql


=



studentsQuery

.ToTraceString();//sql就是生成的sql语句




(2)

在EF 4之后,我们可以直接调用DbQuery<>的



ToString()



方法得到所生成的SQL。



也就是上面的


studentsQuery直接ToString



string


sql


=



studentsQuery

.ToTraceString();//可以猜到,这

里的ToString()方法其实也就是调用了ObjectQuery<>的ToTraceString()方法。




(3)

上面的方法我们无法得到新增或者删除数据时生成的sql。如果想得到这写操作生成的sql,

EF6.1给我们提供了相应的方法。






2、

EF6.1也出来不少日子了,6.1相比6.0有个很大的特点就是新增了


System.Data.Entity.Infrastructure.Interception


命名空间,此命名空间下的对象可以允许我们更加方便的了解到EF运行时的一些信息,当然我们最想看的还是EF生成的Sql语句。







2.1 首先要写一个类继承DbCommandInterceptor。








using System.Data.Entity.Infrastructure.Interception;




using System.Diagnostics;









class EFIntercepterLogging : DbCommandInterceptor

{


private readonly Stopwatch _stopwatch = new Stopwatch();

public override void ScalarExecuting(System.Data.Common.DbCommand

command

, DbCommandInterceptionContext<object> interceptionContext)

{









//var sql = command.CommandText;//这里可以获得想要的sql语句


base.ScalarExecuting(command, interceptionContext);

_stopwatch.Restart();

}

public override void ScalarExecuted(System.Data.Common.DbCommand

command

, DbCommandInterceptionContext<object> interceptionContext)

{


_stopwatch.Stop();

if (interceptionContext.Exception != null)

{


Trace.TraceError(“Exception:{1} rn –> Error executing command: {0}”, command.CommandText, interceptionContext.Exception.ToString());

}

else

{


Trace.TraceInformation(“rn执行时间:{0} 毫秒rn–>ScalarExecuted.Command:{1}rn”, _stopwatch.ElapsedMilliseconds, command.CommandText);

}

base.ScalarExecuted(command, interceptionContext);

}

public override void NonQueryExecuting(System.Data.Common.DbCommand

command

, DbCommandInterceptionContext<int> interceptionContext)

{


base.NonQueryExecuting(command, interceptionContext);

_stopwatch.Restart();

}

public override void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)

{


_stopwatch.Stop();

if (interceptionContext.Exception != null)

{


Trace.TraceError(“Exception:{1} rn –> Error executing command:rn {0}”, command.CommandText, interceptionContext.Exception.ToString());

}

else

{


Trace.TraceInformation(“rn执行时间:{0} 毫秒rn–>NonQueryExecuted.Command:rn{1}”, _stopwatch.ElapsedMilliseconds, command.CommandText);

}

base.NonQueryExecuted(command, interceptionContext);

}

public override void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)

{


base.ReaderExecuting(command, interceptionContext);

_stopwatch.Restart();

}

public override void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)

{


_stopwatch.Stop();

if (interceptionContext.Exception != null)

{


Trace.TraceError(“Exception:{1} rn –> Error executing command:rn {0}”, command.CommandText, interceptionContext.Exception.ToString());

}

else

{


Trace.TraceInformation(“rn执行时间:{0} 毫秒 rn –>ReaderExecuted.Command:rn{1}”, _stopwatch.ElapsedMilliseconds, command.CommandText);

}

base.ReaderExecuted(command, interceptionContext);

}

}








2.1.1


上面的command.CommandText就是捕获的sql语句。






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





2.2 然后要在程序的入口(Application_Start)注册一条监听器







void Application_Start(object sender, EventArgs e)

{


DbInterception.Add(new EFIntercepterLogging());

}



























版权声明:本文为rj532029887原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。