2013年8月10日 星期六

ASP.NET MVC + NLog + Clutch.Diagnostics.EntityFramework 追蹤 EF 執行的 SQL Command

有關追蹤觀察 Entity Framework 所產生的 SQL Command,在之前我有寫了幾篇文章來做介紹:

觀察 ADO.NET Entity Framework 5.0 產生的 SQL Command 與取得 Entity 對應的 Table Name

觀察 Entity Framework 轉換所產出的 SQL Command

但是在上面兩篇文章裡所介紹的方法都是必須要去添加程式,開發專案的時候總不能每個執行 EF 的地方都要去手動加入程式片段,所以我一直找尋一個最簡單而且也不需要對專案程式再去做修改的解決方式。

其實現在有很多方法可以去追蹤觀察 EF 所產生的 SQL Command,但往往都需要過多的配置或者是被迫要更改我們已經習慣的開發方式,過多的配置就代表日後的維護困難以及交接的不便,而更改已經習慣的開發方式就影響甚鉅,有時為了需要妥協而採納一個不熟悉也不習慣的方法,這會嚴重影響開發效率,甚至讓原有的開發人員四處碰壁。

剛好今天看到了一篇文章的介紹,並且在自己實際開個專案來測試一下,的確是相當符合我的需求,不需要對原本程式做過多的修改或是更改程式原有結構(或是更換範本),也不需要改變我原來的開發習慣,只要利用已經熟悉的 NLog 並且再加入 Clutch.Diagnostics.EntityFramework 就行了。

 


首先讓大家知道我是看了哪一篇文章後所得到的想法:

ADO.NET Entity Framework CodeFirst 如何输出日志(EF 5.0) - 张善友 - 博客园

其實這一篇文章裡沒有提到 ASP.NET MVC 以及 NLog,但是經由這篇文章的說明還有自己到 Clutch.Diagnostics.EntityFramework 的 GitHub 裡所看到的說明內容,讓我有了這次的作法。

 

Clutch / Clutch.Diagnostics.EntityFramework

https://github.com/Kukkimonsuta/Clutch

image

 

開發環境:Windows 7 + SQL Server 2008 R2 Express + VS2012 + ASP.NET MVC 4 + Entity Framework 5

 

Step.1

開個新的 ASP.NET MVC 4 網站專案,並且增加 ADO.NET 實體資料模型(一樣還是使用 Northwind 資料庫),

image

 

Step.2

因為這邊是做個簡單示範,所以只有建立一個 CategoryController,Scaffold 選項的範本使用「具有讀取寫入動作和檢視、使用 Entity Framework 的 MVC 控制器」來建立 Controller 與 View,

image

 

Step.3

使用 Nuget 為專案加入 NLog 相關套件

image

 

Step.4

使用 NuGet 加入 Clutch.Diagnostics.EntityFramework 套件(Clutch 因為相依性關係也會自動加入)

image

 

Step.5

依照 Clutch.Diagnostics.EntityFramework 的範例說明,在 Global.asax 裡的 Application_Start() 加入以下的程式,

protected void Application_Start()
{
    DbTracing.Enable(
        new GenericDbTracingListener()
            .OnFinished(c => logger.Trace("-- Command finished - time: {0}{1}{2}", c.Duration, Environment.NewLine, c.Command.ToTraceString()))
            .OnFailed(c => logger.Trace("-- Command failed - time: {0}{1}{2}", c.Duration, Environment.NewLine, c.Command.ToTraceString()))
    );
}

完整的 Global.asax 如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Clutch.Diagnostics.EntityFramework;
using NLog;
 
namespace MvcApplication1
{
    // 注意: 如需啟用 IIS6 或 IIS7 傳統模式的說明,
    // 請造訪 http://go.microsoft.com/?LinkId=9394801
 
    public class MvcApplication : System.Web.HttpApplication
    {
        private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
 
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
 
            DbTracing.Enable(
                new GenericDbTracingListener()
                    .OnFinished(c => logger.Trace("-- Command finished - time: {0}{1}{2}", 
                        c.Duration, Environment.NewLine, 
                        c.Command.ToTraceString()))
                    .OnFailed(c => logger.Trace("-- Command failed - time: {0}{1}{2}", 
                        c.Duration, Environment.NewLine, 
                        c.Command.ToTraceString()))
            );
        }
    }
}

 

Step.6

因為是要透過 NLog 將追蹤 EF 所產生的 SQL Command 給顯示到 Visual Studio 的偵錯輸出視窗中,而有關這部份的作法在之前文章有相關說明:「NLog 輸出記錄資訊到 Visual Studio Output 視窗」,而我在 Nlog.Config 的配置內容如下:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 
    <!-- 
  See http://nlog-project.org/wiki/Configuration_file 
  for information on customizing logging rules and outputs.
   -->
    <targets>
        <!-- add your targets here -->
 
        <target name="debugger" xsi:type="Debugger"
                layout="
==========================================================================${newline}
DateTime: ${longdate}${newline}
Level: ${level:uppercase=true}${newline}
Logger: ${logger}${newline}
Message: ${newline}
${message}${newline}
Exception: ${exception:format=tostring}${newline}
==========================================================================${newline}" />
    </targets>
 
    <rules>
        <!-- add your logging rules here -->
        <logger name="*" minlevel="Trace" writeTo="debugger" />
    </rules>
</nlog>

 

完成以上的步驟之後就完成了,接著就是執行網站來觀察 EF 所產生的 SQL Command 是否會輸出到 Output 視窗,

Category/Index

image

Category/Details

image

Category/Edit

image

Category/Create

image

Category/Delete

image

 

以上

3 則留言:

  1. 請問是否有目前asp.net core 3.0部分sql command記錄方式,因為相關檔案格式及設定不同謝謝

    回覆刪除
    回覆
    1. .net core 就忽略這工具
      ef core 有提供輸出 sql command 的功能,不過這要請你自己去找囉

      刪除
    2. https://docs.microsoft.com/zh-tw/archive/msdn-magazine/2018/october/data-points-logging-sql-and-change-tracking-events-in-ef-core

      刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。