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

今天我们来聊聊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进行讨论.欢迎.


相关文章:


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


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329252.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日期相减 python_如果将excel的数字转化为日期(高级教程)

不知道大家有没有这样的体会&#xff0c;明明我们在单元格里输入的是一个日期&#xff0c;但是excel却提示我们输入的是一个数字&#xff0c;这个东西就很奇怪了&#xff0c;43471怎么就成了日期了那&#xff1f;实际上这和计算机的底层设置有关系&#xff0c;计算机是无法直接…

JSOUP 教程—— Java爬虫,简易入门,秒杀htmlparser

转载自 JSOUP 教程—— Java爬虫&#xff0c;简易入门&#xff0c;秒杀htmlparser关于爬虫&#xff0c;之前一直用做第一个站的时候&#xff0c;记得那时候写的 爬虫 是爬sina 的数据&#xff0c;用的就是 htmlparser 可能是由于好奇和满足我当时的需求&#xff0c;那开始就各…

3到6年的.NETer应该掌握哪些知识

我们组的开发人力一直比较紧张&#xff0c;今年春节后&#xff0c;高层终于给了几个headcount&#xff0c;我们可以开始招人了。从三月初我们就开始找简历&#xff0c;渠道有拉钩&#xff0c;内推&#xff0c;我司自己的招聘网站和智联等。简历筛了很多&#xff0c;也打了很多电…

多边形上点的顺序排序_一种寻找多边形视觉中心的新算法

遇到的问题在一个多边形上放置文本标签或工具提示的最佳位置通常位于其“视觉中心”的某个位置&#xff0c;即多边形内部的一个点&#xff0c;周围有尽可能多的空间。计算这样一个中心首先想到的是多边形质心。你可以用一个简单快速的公式计算多边形中心&#xff0c;但如果形状…

通过Jexus 部署 dotnetcore版本MusicStore 示例程序

ASPNET Music Store application 是一个展示最新的.NET 平台&#xff08;包括.NET Core/Mono等&#xff09;上使用MVC 和Entity Framework的示例程序&#xff0c;本文将展示如何在CentOS上运行.NET Core版本的MusicStore&#xff0c;并通过Jexus对外发布。 上篇文章 《结合Jexu…

java爬虫之基于httpclient的简单Demo(二)

转载自 java爬虫之基于httpclient的简单Demo(二)延续demo1的 java爬虫的2种爬取方式&#xff08;HTTP||Socket&#xff09;简单Demo(一)&#xff0c;demo2出炉啦&#xff0c;大家想学爬虫都可以从这个网盘学习哦&#xff1a;https://pan.baidu.com/s/1pJJrcqJ#list/path%2F 免费…

神经网络中的最小二乘_深度神经网络:噪声中解读出科学

该研究介绍了一种基于深度神经网络的基本新方法&#xff0c;以基于已知的物理模型将函数形式拟合到噪声数据。来自美国橡树林国家实验室的Stephen Jesse领导的团队&#xff0c;提出了一种新的方法&#xff0c;可用来逆向解决问题&#xff0c;可从基于光谱成像数据的最小二乘拟合…

微软开放Holographic平台,意在统一VR的操作系统?

在刚刚结束的台北电脑展上&#xff0c;微软没有发布很多新品&#xff0c;而是宣布向第三方开放Windows Holographic&#xff08;全息&#xff09;平台&#xff0c;鼓励其他VR/AR头显使用该平台。近日外媒engadget发表文章&#xff0c;文中作者讲述了微软的野心&#xff0c;有意…

java爬虫的2种爬取方式(HTTP||Socket)简单Demo(一)

转载自 java爬虫的2种爬取方式&#xff08;HTTP||Socket&#xff09;简单Demo(一)最近在找java的小项目自己写着玩&#xff0c;但是找不到合适的&#xff0c;于是写开始学一点爬虫&#xff0c;自己也是感觉爬虫比较有趣。这里自己找了一个教程&#xff0c;这一次写的是基于Sock…

linux mysql复制一个表结构图_详解Windows和Linux下从数据库导出表结构,以及Linux下如何导入.sql文件到MySQL数据库...

本文首先讲解window下如何使用Navicat for MySQL导出表。1、如下图所示&#xff0c;目标数据库是mydatabase&#xff0c;数据库中有四张表。2、选中该数据库&#xff0c;右键——数据传输。3、左边可以选择要导出哪几张表&#xff0c;右边选择.sql文件的存储位置。4、在高级中&…

基于Jenkins快速搭建持续集成环境

看了园友张善友的博文,尝试成功.便有此作.原网址: 基于 Jenkins 快速搭建持续集成环境 天下事有难易乎?为之,则难者亦易矣&#xff1b;不为,则易者亦难矣. 首先要学会使用MSBuild构建脚本 附网址:http://www.infoq.com/cn/articles/MSBuild-1. 目标:学会用MSBuild编译程序,主要…

零基础写Java知乎爬虫之进阶篇

转载自 零基础写Java知乎爬虫之进阶篇前面几篇文章&#xff0c;我们都是简单的实现了java爬虫抓取内容的问题&#xff0c;那么如果遇到复杂情况&#xff0c;我们还能继续那么做吗&#xff1f;答案当然是否定的&#xff0c;之前的仅仅是入门篇&#xff0c;都是些基础知识&#x…

MySQL导入冲突保留两者_面试被问MySQL 主从复制,怎么破?

一、前言随着应用业务数据不断的增大&#xff0c;应用的响应速度不断下降&#xff0c;在检测过程中我们不难发现大多数的请求都是查询操作。此时&#xff0c;我们可以将数据库扩展成主从复制模式&#xff0c;将读操作和写操作分离开来&#xff0c;多台数据库分摊请求&#xff0…

“.Net 社区虚拟大会”(dotnetConf) 2016 Day 1 Keynote: Scott Hunter

“.Net 社区虚拟大会”(dotnetConf) 2016 今天凌晨在Channel9 上召开&#xff0c;在Scott Hunter的30分钟的 Keynote上没有特别的亮点&#xff0c;所讲内容都是 微软“.Net社区虚拟大会”dotnetConf2015&#xff1a;关键词&#xff1a;.NET 创新、开源、跨平台 的具体化&#x…

Java(enum)枚举用法详解

转载自 Java&#xff08;enum&#xff09;枚举用法详解本篇文章主要介绍了Java 枚举用法详解&#xff0c;枚举的好处&#xff1a;可以将常量组织起来&#xff0c;统一进行管理。有兴趣的可以一起来了解一下。概念 enum的全称为 enumeration&#xff0c; 是 JDK 1.5 中引入的新特…

python处理脑电信号_用ICA去除脑电信号中的眼球链接

你有没有注意到你的“组件”完全是原始信号的比例和颠倒&#xff1f;这是因为你不能得到比信号更多的成分。在您需要执行以下步骤&#xff1a;将所有EEG通道输入ICA手动移除包含眨眼或其他伪影的组件用反变换重构让我们详细了解第2步&#xff1a;为什么要手动删除组件&#xff…

ASP.NET Core 中文文档 第一章 入门

原文&#xff1a;Getting Started翻译&#xff1a;娄宇(Lyrics)校对&#xff1a;刘怡(AlexLEWIS) 1、安装 .NET Core 2、创建一个新的 .NET Core 项目&#xff1a; mkdir aspnetcoreappcd aspnetcoreapp dotnet new 3、编辑 project.json 文件&#xff0c;添加 Kestrel HTTP se…

Properties文件的XML格式

转载自 Properties文件的XML格式 想必大家都用过*.properties文件&#xff0c;作为配置文件。但是&#xff0c;如果该文件写入了中文&#xff0c;待编译后内容就会成为乱码&#xff0c;使用native命令也好、使用ant执行编码转换也好&#xff0c;多少有点麻烦&#xff0c;与其如…

python简单爬虫课题_VS2019python爬虫入门

VS2019新建python项目在vs2019中添加python编译环境创建python控制台应用程序项目配置python环境安装requests第三方库管理程序包&#xff0c;执行安装requests包命令pip install requests导入第三方包import requests简单爬虫编写import requestsif __name__ "__main__&…

“.Net 社区虚拟大会”(dotnetConf) 2016 Day 2 Keynote: Miguel de Icaza

美国时间 6月7日--9日&#xff0c;为期三天的微软.NET社区虚拟大会正式在 Channel9 上召开&#xff0c;美国时间6.8 是第二天&#xff0c; Miguel de Icaza 做Keynote&#xff0c;Miguel 在波士顿Xamarin的办公室&#xff0c;所以使用了Skype。 class"video_iframe" …