您好,登錄后才能下訂單哦!
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()); }
這樣我們就完成了整個監聽的過程了~
關于EntityFramework的記錄日志方式以及記錄錯誤并分析執行時間過長原因是什么問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。