C# 获取EF savechanges() 的增删改的SQL语句

如何获取SaveChanges()的SQL语句。

目的: 在涉及到数据库的项目中,增删改是非常关键的操作,最好是详细的记录到日志中,而详细 莫过于直接将SQL语句记录到数据库日志中了。

像下面这个方法里面的就相当于UPDATE了,属于关键性操作

private void UpdatePredictionState(List<Guid> ids)
        {
            foreach (var id in ids)
            {
                var prediction = _context.PredictionInfos.Find(id);
                prediction.State = 2;
                _context.SaveChanges();
            }
        }

 那么如何获取_context.SaveChanges()的SQL语句呢?

第一步:展示SQL语句

EF6 有关于日志的一个方法来专门获取数据库事务的语句(我也是因为这个才知道什么叫数据库的事务,之前学过没有实践也就忘了-----(事务:简单来说是数据库操作中的最小单位,可以看做是一次的增删改查,不知道这么理解对不对,不对的话 请大神们指教))context.Database.log    这个我在网上查了好久,因为是萌新 不会用!!!!然后我就请教大神了(手动滑稽)。

具体用法如下:

public DownholeToolsTypeController(LoggingJobContext context):base("下井仪器类型")
        {
            _context = context;

            _context.Database.Log = s =>
            {
                Console.WriteLine(s);
            };
        }

将这个写在控制器的构造器里面,每当运行方法时会先运行构造器然后运行指定的方法,这样运行方法时,就会监听有没有数据库的事务,有的话就会将事务输出到控制台上,运行结果如下:

 

 

 这样会把所有的数据库事务都写出来,既然能获取出来了,那么写入数据库就不是很难了。

但是select 不是我们所说的关键性记录啊,我们只要增!删!改!!!

不难,但是作为萌新,我用了最笨的办法获取到了我需要的数据

 _loggingJobContext.Database.Log = s =>
            {
                string sqlstr="";

                if (sw == 1)
                {
                    sqlstr += s;
                }

                if (s.Length > 12)
                {
                    if (s.Substring(0, 6) == "INSERT" || s.Substring(0, 6) == "UPDATE" || s.Substring(0, 6) == "DELETE")
                    {
                        sqlstr += s;
                        sw = 1;
                    }
                    if (s.Substring(0, 13).Contains("Completed") && s.Substring(s.Length - 3, 1) == "1")
                    {
                        sw = 0;
                    }
                }

                _sqlStrBuilder.AppendLine(sqlstr);

  当然 前面的变量:StringBuilder _sqlStrBuilder=new StringBuilder(); int sw = 0;必不可少的。

经过研究发现,打开关闭连接对我们是没有用的,最有用的其实就是sql语句以数据变量 还有完成结果

这样就可以只记录增删改的操作记录了;

但是,每一个控制器都要这么写,麻烦,于是我想简单一些,叫代码重用,咋弄呢,我写了个类,想引用这个类,发现不行,于是请教大神,大神就教我做人了(教我知道什么是父类了,其实知道什么是父类,但是写的少,压根没有往父类上想)

第二步:

代码重用问题,由于日志问题,大神们已经写好了父类方法了,但是基本上并没有SQL语句的方法,于是我把我上面的代码放到了父类的构造器里面

并在下图2里面添加了 有关url的语句  这样 日志就会记载访问的是哪个url和 sql语句是啥 都有了。

 

 

 上这个图的目的 也是为了记录一下,并且让自己记住,OnActionExecuting和OnActionExecuted的执行先后顺序,先执行子类的构造器 然后执行父类的构造器,然后执行OnActionExecuting方法再执行子类的方法,最后执行OnActionExecuted方法。所以最后记录的方法写在OnActionExecuted里面是表示着 最终的记录。

大神最后,给我说了一些知识点,说是要检查的:知识点我会放在下面,然后如果学习有心得,我会继续写博客的。

大神说上述问题有关的知识点:

实例化子类对象时,子类、父类、父父类构造器的执行顺序
调用父类构造器的意义
用父类或抽象类类型的变量编程的意义
虚函数

Controller对象的生命周期

posted @ 2020-03-20 09:16  逆销  阅读(2439)  评论(0编辑  收藏  举报