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
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.
The notes for EF / Code First, state that your factory and other code must be run BEFORE
any EF stuff, which leads me to suspect that installing this code in Application_Start is too late. Try creating a pre-start class, as follows:
[assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.App_Start.AppStart_MiniProfiler), "Start")]
namespace MyApp.App_Start
{
[INSERT using DECLARATIONS]
public static class AppStart_MiniProfiler
{
public static void 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;
}
}
}
Create an App_Start folder in your project, and place this class in the App_Start folder.
精彩评论