日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2023/12/4 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天我們來聊聊EF的日志記錄.

一個好的數(shù)據(jù)庫操作記錄不僅僅可以幫你記錄用戶的操作,

更應該可以幫助你獲得效率低下的語句來幫你提高運行效率

廢話不多說,我們開始

?

環(huán)境和相關技術

本文采用的環(huán)境與技術

系統(tǒng):WIN7

數(shù)據(jù)庫:SQL Server2008

相關技術:MVC5 ? ? EF6.0+

簡單的記錄

一、修改配置文件

我們先來看看最簡化的EF日志記錄,任何代碼都不用改,在你的配置文件中加入如下配置即可自動記錄:

在你的EntityFramework節(jié)點下加入如下配置即可(這里需要注意的是第一個參數(shù)是你日志的輸出地址):

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

?

通過低級監(jiān)聽接口來進行監(jiān)聽

如果你只是想單純的記錄,上面兩種方式應該就能滿足你了.

我們記錄的目的其實最重要的還是在于分析性能 下面就開始我們的重頭戲.

采用IDbCommandInterceptor接口進行EF的監(jiān)聽

首先我們來看看這個接口里面到底有些什么:

寫過ADO.NET的人 應該對這些單詞很熟悉了吧.(因為EF最終訪問數(shù)據(jù)庫的方式還是用的ADO.NET)

注意:每個執(zhí)行都有ed(執(zhí)行完成后的監(jiān)聽)和ing(執(zhí)行時的監(jiān)聽)

下面我們來一步一步實現(xiàn)這個接口

首先定義一個類(名字你隨意):

//名字可以隨意,但是肯定要繼承我們的監(jiān)聽接口 - - ,
public class DatabaseLogger : IDbCommandInterceptor { }

然后我們繼續(xù),

定義一個靜態(tài)只讀的ConcurrentDictionary作為我們的記錄倉儲,考慮到數(shù)據(jù)訪問時多線程的情況很常見,所以我們采用線程安全的ConcurrentDictionary

代碼如下:

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

接下來,我們來實現(xiàn)我們所需要的兩個方法 一個為onStart來記錄SQL語句執(zhí)行開始的時間

如下:

//記錄開始執(zhí)行時的時間private static void OnStart(DbCommand command){MStartTime.TryAdd(command, DateTime.Now);}

然后實現(xiàn)我們的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(); //循環(huán)獲取執(zhí)行語句的參數(shù)值foreach (DbParameter param in command.Parameters){parameters.AppendLine(param.ParameterName + " " + param.DbType + " = " + param.Value);}
//判斷語句是否執(zhí)行時間超過1秒或是否有錯if (duration.TotalSeconds > 1 || interceptionContext.Exception!=null){
//這里編寫記錄執(zhí)行超長時間SQL語句和錯誤信息的代碼}
else{
//這里編寫你自己記錄普通SQL語句的代碼}
}

既然我們已經(jīng)得到了想要的東西,那具體的記錄方式,各位仁者見仁 智者見智 就隨意了,所以我這就不寫了.

然后接著,我們要實現(xiàn)這個接口的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執(zhí)行我們之前寫的OnStart方法,所有的ed執(zhí)行我們的log方法即可.

接下來,我們需要注入這個接口:

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

protected void Application_Start() { //注入自己寫的監(jiān)聽DbInterception.Add(new MiniProfiler_EFModel.DatabaseLogger()); }

這樣我們就完成了整個監(jiān)聽的過程了~

實現(xiàn)效果如下:

我們得到了執(zhí)行的秒數(shù)

得到了執(zhí)行的SQL語句:

得到了SQL語句所對應的參數(shù):

大功告成!

寫在最后

這里我只是幫各位通過監(jiān)聽來獲取到相關的信息,具體如何優(yōu)化,應該用什么東西進行記錄,我就不過多的贅述,這是屬于仁者見仁智者見智的東西,不過有興趣的可以通過博客加我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社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

贊賞

人贊賞

總結(jié)

以上是生活随笔為你收集整理的EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。