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

来源:互联网 发布:linux sleep longer 编辑:程序博客网 时间:2024/04/30 09:11

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());
        }



0 0
原创粉丝点击