Search code examples
asp.net-mvc-3ef-code-firstmvc-mini-profiler

MvcMiniProfiler will not show database profiling when using code first and repository pattern


I am trying to setup database profiling with my ASP.NET MVC3 application. I have followed every blog I can find about this and the result is:

In web.config:

<system.data>
  <DbProviderFactories>
    <remove invariant="MvcMiniProfiler.Data.ProfiledDbProvider" />
    <add name="MvcMiniProfiler.Data.ProfiledDbProvider" invariant="MvcMiniProfiler.Data.ProfiledDbProvider" description="MvcMiniProfiler.Data.ProfiledDbProvider" type="MvcMiniProfiler.Data.ProfiledDbProviderFactory, MvcMiniProfiler, Version=1.6.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3" />
  </DbProviderFactories>
</system.data>

In Global.asax:

protected void Application_Start()
{
    Bootstrapper.Run();

    MiniProfiler.Settings.SqlFormatter = new SqlServerFormatter();

    var factory = new SqlConnectionFactory(ConfigurationManager.ConnectionStrings["TemplateDB"].ConnectionString);
    var profiled = new MvcMiniProfiler.Data.ProfiledDbConnectionFactory(factory);

    Database.DefaultConnectionFactory = profiled;
}

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

protected void Application_EndRequest()
{
    MiniProfiler.Stop();
}

In controller:

public ActionResult About()
{
    var profiler = MiniProfiler.Current;

    using (profiler.Step("call database"))
    {
        ProjectResult result = projectService.Create("slug");

        return View();
    }
}

I am using the repository patterns and my EF Code first lives in another project that is referenced by the MVC application.

My database class looks like:

public class Database : DbContext
{
    public Database(string connection) : base(connection)
    {
    }

    public DbSet<Project> Projects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Project>().Property(p => p.Slug).IsUnicode().IsRequired().IsVariableLength().HasMaxLength(64);
    }

    public virtual void Commit()
    {
        base.SaveChanges();
    }
}

My database factory looks like:

public class DatabaseFactory : Disposable, IDatabaseFactory
{
    private readonly string connectionString;
    private Database database;

    public DatabaseFactory(string connectionString)
    {
        Check.Argument.IsNotNullOrEmpty(connectionString, "connectionString");

        this.connectionString = connectionString;
    }

    public Database Get()
    {
        return database ?? (database = new Database(connectionString));
    }

    protected override void DisposeCore()
    {
        if (database != null)
            database.Dispose();
    }
}

When I run my application the profiler will not show any database profiling at all, just the regular execution time of the controller/view.

Any help is appreciated.

Thanks


Solution

  • Solved by installing the Nuget MiniProfiler and MiniProfiler.EF package. Add the following in the Global.asax

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

    And finally add the below code to the head tage below JQuery of your markup.

    @MvcMiniProfiler.MiniProfiler.RenderIncludes()
    

    You're set. Works like a charm.