今天我们来聊聊EF的日志记录.

一个好的数据库操作记录不仅仅可以帮你记录用户的操作,

更应该可以帮助你获得效率低下的语句来帮你提高运行效率

废话不多说,我们开始

环境和相关技术

本文采用的环境与技术

系统:WIN7

数据库:SQL Server2008

相关技术:MVC5     EF6.0+

简单的记录

一、修改配置文件

我们先来看看最简化的EF日志记录,任何代码都不用改,在你的配置文件中加入如下配置即可自动记录:

在你的EntityFramework节点下加入如下配置即可(这里需要注意的是第一个参数是你日志的输出地址):

<interceptors><interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework"><parameters><parameter value="D:\ttt\log.txt" /><parameter value="true" type="System.Boolean" /></parameters></interceptor></interceptors>

我们到对应的地址下就能找相关的日志文件了如下:

二、简单封装:

编写一个自己的DBContext的基类如下:

 public class DataBaseContext<T> : DbContext where T:class,new()
{    //重写SaveChanges方法public override int SaveChanges(){              string sql = "";  //记录实体操作日志this.Database.Log = (a) =>{sql += a;}; //这里的sql就是操作日志了.return base.SaveChanges();}
}

通过低级监听接口来进行监听

如果你只是想单纯的记录,上面两种方式应该就能满足你了.

我们记录的目的其实最重要的还是在于分析性能 下面就开始我们的重头戏.

采用IDbCommandInterceptor接口进行EF的监听

首先我们来看看这个接口里面到底有些什么:

写过ADO.NET的人 应该对这些单词很熟悉了吧.(因为EF最终访问数据库的方式还是用的ADO.NET)

注意:每个执行都有ed(执行完成后的监听)和ing(执行时的监听)

下面我们来一步一步实现这个接口

首先定义一个类(名字你随意):

//名字可以随意,但是肯定要继承我们的监听接口 - - , public class DatabaseLogger : IDbCommandInterceptor
{
}

然后我们继续,

定义一个静态只读的ConcurrentDictionary作为我们的记录仓储,考虑到数据访问时多线程的情况很常见,所以我们采用线程安全的ConcurrentDictionary

代码如下:

 public class DatabaseLogger : IDbCommandInterceptor{            static readonly ConcurrentDictionary<DbCommand, DateTime>       MStartTime = new ConcurrentDictionary<DbCommand, DateTime>();}

接下来,我们来实现我们所需要的两个方法 一个为onStart来记录SQL语句执行开始的时间

如下:

//记录开始执行时的时间private static void OnStart(DbCommand command){MStartTime.TryAdd(command, DateTime.Now);}

然后实现我们的log方法来记录相关的SQL语句和错误信息

 rivate static void Log<T>(DbCommand command,   DbCommandInterceptionContext<T> interceptionContext)
{DateTime startTime;TimeSpan duration;           //得到此command的开始时间MStartTime.TryRemove(command, out startTime);               if (startTime != default(DateTime)){duration = DateTime.Now - startTime;}            elseduration = TimeSpan.Zero;                      var parameters = new StringBuilder(); //循环获取执行语句的参数值foreach (DbParameter param in command.Parameters){parameters.AppendLine(param.ParameterName + " " + param.DbType + " = " + param.Value);}                       //判断语句是否执行时间超过1秒或是否有错if (duration.TotalSeconds > 1 || interceptionContext.Exception!=null){                                //这里编写记录执行超长时间SQL语句和错误信息的代码}                      else{                                //这里编写你自己记录普通SQL语句的代码}  }

既然我们已经得到了想要的东西,那具体的记录方式,各位仁者见仁 智者见智 就随意了,所以我这就不写了.

然后接着,我们要实现这个接口的6个方法,如下:

 public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{Log(command, interceptionContext); }      

 public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext){OnStart(command);}       

  public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext){Log(command, interceptionContext);}   

  public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext){OnStart(command);}        public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext){Log(command, interceptionContext);}     

  public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext){      OnStart(command);}

其实很简单,就是所有的ing执行我们之前写的OnStart方法,所有的ed执行我们的log方法即可.

接下来,我们需要注入这个接口:

这里我的Demo用的MVC所以我就在 Application_Start()中直接注入了,如下:

protected void Application_Start()
{          //注入自己写的监听DbInterception.Add(new MiniProfiler_EFModel.DatabaseLogger());
}

这样我们就完成了整个监听的过程了~

实现效果如下:

我们得到了执行的秒数

得到了执行的SQL语句:

得到了SQL语句所对应的参数:

大功告成!

写在最后

这里我只是帮各位通过监听来获取到相关的信息,具体如何优化,应该用什么东西进行记录,我就不过多的赘述,这是属于仁者见仁智者见智的东西,不过有兴趣的可以通过博客加我QQ进行讨论.欢迎.

相关文章:

  • 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)

  • 第一篇 Entity Framework Plus 之 Audit

  • 第二篇 Entity Framework Plus 之 Query Future

  • 第三篇 Entity Framework Plus 之 Query Cache

  • 第四篇 Entity Framework Plus 之 Batch Operations

  • Entity Framework教程(第二版)

  • Dapper、Entity Framework 和混合应用

  • .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介

原文地址:http://www.cnblogs.com/GuZhenYin/p/5556732.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

赞赏

人赞赏

EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因相关推荐

  1. python记录日志_记录python日志

    在线运行的应用就是黑盒子,需要被跟踪监控.最简单也最重要的方式就是记录日志.记录日志允许我们在开发软件的同时,让程序在系统运行时发出信息,这些信息对于我们和系统管理员来说都是有用的. 就像为将来的程序 ...

  2. asp.net记录错误日志的方法

    1.说明 在调试发布后的asp.net项目时有可能会遇到意想不到的错误,而未能及时的显示.这就需要记录日志来跟踪错误信息,所以写了个简单的记录信息的方法,记录简单的文本信息也可以使用.此方法是以生成文 ...

  3. Sql 学习查询多种条件(记录自己常用一些方法,本人学习用)

    Sql 学习查询多种条件(记录自己常用一些方法,本人学习用) 根据 PROCDEFID 对表 BO_ACT_MPDL_PROCESS 最后就行查重 查出多余重复的数据 1.in和exists 方式二: ...

  4. mysql表的设计几种方式_支持多种登录方式的数据表设计 | 六阿哥博客

    一个带有用户系统的应用最基本登录方式是站内账号登录,但这种方式往往不能满足我们的需求.现在的应用基本都有站内账号.email.手机和一堆第三方登录,那么如果需要支持这么多种登录方式,或者还有银行卡登录 ...

  5. 工作经验:Java 系统记录调用日志,并且记录错误堆栈

    前言:现在有一个系统,主要是为了给其他系统提供数据查询接口的,这个系统上线不会轻易更新,更不会跟随业务系统的更新而更新(这也是有一个数据查询接口系统的原因,解耦).这时,这个系统就需要有一定的方便的线 ...

  6. 辅助类——记录错误信息

    记录错误信息 Debug游戏代码可能是非常复杂的,特别是如果您没有得到任何异常,但某些渲染循环却出错.只设置几个断点并不够,尤其是如果游戏在运行一段时间之后遇到错误,Debug并不是正确的选择.您想知 ...

  7. PHP项目中,记录错误日志

    一.场景介绍: 环境:LNMP 我们通常是通过nginx的错误日志来分析分错的,也就是我们在各个server中定义的error_log. 比如下面这样,就是将错误日志定义在/etc/nginx/log ...

  8. 分布式锁的多种实现方式

    转载自 分布式锁的多种实现方式 目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们"任何一个分布式系统都无法同时满足 ...

  9. java异步处理同步化_java 异步查询转同步多种实现方式:循环等待,CountDownLatch,Spring EventListener,超时处理和空循环性能优化...

    异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 正常处理逻辑 触发异步操作,然后传递一个唯一标识. 等到异步结果返回,根据传入的唯一标识,匹配此次结果. 如何转换为同步 ...

最新文章

  1. 使用PlanAhead查看Virtex-7系列FPGA的底层架构
  2. Java开发软件安装及配置
  3. 【2021最新版】如何clean或者install Maven项目——IntelliJ IDEA系列教程
  4. mysql慕课网笔记_mysql学习笔记
  5. 1015 德才论 (25分)
  6. mysql5.5 5.7区别_mysql 5.5 和5.7 安装的区别
  7. javascript 高级程序设计_所以 JavaScript 到底是什么?我居然懵了????
  8. 如今市面上有哪些可以远程的软件?
  9. arduino 有源 蜂鸣器_Arduino入门教程--第八课--用蜂鸣器模拟警报器
  10. 2022年华为杯中国研究生数学建模竞赛C题思路
  11. 多浏览器支持ActiveX控件
  12. GIM三维建模设计软件
  13. npm 错误 ETIMEDOUT
  14. vue 后台管理系统富文本组件(四)UEditor(集成 135 编辑器插件)
  15. Vue + element 实现课程表
  16. VS2013好用的插件
  17. 户外带什么耳机好、户外骨传导耳机推荐
  18. URP管线下使用Dither做像素化风格
  19. Oracle数据库的整体结构
  20. webp文件如何进行格式转换

热门文章

  1. Python: logging日志模块简单示例
  2. left outer join 和 right outer join 和 join 的区别
  3. Zune 3.0与XNA GS 3.0 Beta
  4. Fiddler抓包一键生成调用代码
  5. 码农身份得到正式认证
  6. WPF任务栏同步进度
  7. 使用WebBenchmark对webapi进行管理和性能测试
  8. gRPC真要取代WebApi了,你还学得过来吗?
  9. EntityFramework Core 3.x上下文构造函数可以注入实例呢?
  10. ASP.NET Core+Quartz.Net实现web定时任务