Azureはじめました

Windows Azureで業務システムを組んでみる日記

MVC4+EF6でMiniProfilerを使う

MiniProfiler

ProfilingにMiniProfilerを使う場合NuGetで

PM> Install-Package MiniProfiler
PM> Install-Package MiniProfiler.Mvc
PM> Install-Package MiniProfiler.EF

でやればいいんだけど、EF6を使ってる場合ObjectContextあたりの仕様変更のせいでうまいこと動かない。


検索してみたら
Dave Paquette | Running MiniProfiler.EF with Entity Framework 6 RC1

Last week, I tried testing some of the new EF6 features in my usual sample application. Unfortunately, the application crashed because the version of MiniProfiler.EF I was referencing only works with EF4/5. As someone pointed out on Mini Profiler community forum, EF6 support was added to GitHub but is not yet available in the Nuget package.
I am too impatient to wait for a new Nuget package, so I went over to Github and cloned the MiniProfiler repo.
Upon inspecting the MiniProfiler solution, I noticed there are 2 Entity Framework related projects: StackExchange.Profiling.EntityFramework and StackExchange.Profiling.EntityFramework6.

適当翻訳:MiniProfiler.EFはEF6じゃ動かないけどNuGetパッケージ化されてないのが本家Gitにあったよ。

とのこと。

おし。

本家から検索

MiniProfiler/StackExchange.Profiling.EntityFramework6 at master · SamSaffron/MiniProfiler · GitHub

確かに入ってた。

Git CloneしてStackExchange.Profiling.EntityFramework6をビルド。
出来上がったライブラリを参照設定に追加する。
f:id:twisted0517:20131010161257p:plain

MVC4用の設定

MiniProfiler.csをMiniProfiler.MVC3.Package/Content/AppStart/Miniprofiler.cs.ppを元に作る*1

MiniProfiler/MiniProfiler.MVC3.Package/Content/App_Start/MiniProfiler.cs.pp at master · SamSaffron/MiniProfiler · GitHub

Global.aspxの変更

リクエスト時にProfilerが動くように以下のように変更

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;
using Microsoft.WindowsAzure.ServiceRuntime;
using WebMatrix.WebData;
using StackExchange.Profiling;
using StackExchange.Profiling.Data;

namespace MyMVC{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication {
        protected void Application_Start() {
            /* BundleConfig.RegisterBundles()とかの諸々 */

            MiniProfilerEF.Initialize();
            System.Data.Entity.DbConfiguration.Loaded += (sender, a) =>
    a.ReplaceService<System.Data.Entity.Core.Common.DbProviderServices>(
            (services, o) =>
                EFProfiledSqlClientDbProviderServices.Instance);
        }

        protected void Application_BeginRequest() {
            if (Request.IsLocal) {
                MiniProfiler.Start();
            }
        }
        protected void Application_EndRequest() {
            MiniProfiler.Stop();
        }
    }
}

↓の記事にある
Dave Paquette | Running MiniProfiler.EF with Entity Framework 6 RC1

DbConfiguration.Loaded += (sender, a) => 
    a.ReplaceService(
            (services, o) => 
                EFProfiledSqlClientDbProviderServices.Instance);

は「ReplaceServiceの型推論ができねーからきちんと設定しろ」的なエラーになったので

System.Data.Entity.DbConfiguration.Loaded += (sender, a) =>
    a.ReplaceService<System.Data.Entity.Core.Common.DbProviderServices>(
            (services, o) =>
                EFProfiledSqlClientDbProviderServices.Instance);

という感じで動かした。

結果

f:id:twisted0517:20131010151549p:plain

SQLがきちんとプロファイルの対象になってる。

いやー、こんなのが簡単に出来るようになるとかいい時代だのう。

*1:$rootnamespace$をMVCプロジェクトのルートネームスペースに置き換えるだけ