Mini Profiler and Linq2DB in .NET MVC


#1

I have a task to add miniprofiler to a .NET MVC 5 application. So far I have done this and it works:

  • Installed NuGet packages for MiniProfiler and MiniProfiler.MVC4

  • Added @MiniProfiler.RenderIncludes() to shared View:

    @using StackExchange.Profiling;
    ...
    // before closing body tag
    @MiniProfiler.RenderIncludes(position: RenderPosition.BottomLeft)  
    
  • Added necessary start and stop code to Global.asax.cs:

    protected void Application_BeginRequest()
    {
        if (Request.IsLocal)
            MiniProfiler.Start();
    }
    
    protected void Application_EndRequest()
    {
        MiniProfiler.Stop();
    }
    
  • Added necessary methods to ControllerBase.cs (OnActionExecuting, OnResultExecuting, and OnResultExecuted)

    #region MiniProfiler
    private IDisposable step;
    
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        using (MiniProfiler.Current.Step("OnActionExecuting"))
        {
            base.OnActionExecuting(filterContext);
        }
    }
    
    protected override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        step = MiniProfiler.Current.Step("OnResultExecuting");
        base.OnResultExecuting(filterContext);
    }
    
    protected override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        step?.Dispose();
        base.OnResultExecuted(filterContext);
    }
    #endregion
    
  • Added handler to web.config:

      <system.webServer>
        <handlers>
          <add name="MiniProfiler" path="mini-profiler-resources/*" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
        </handlers>
      </system.webServer>
    

With this basic setup I get the profiler results to display on all of my views. Works great and is easy to setup!

The next step is to profile the database. I see support for several db platforms, but I have not found much for Linq2DB.

In this project we have a context class that looks something like:

public class SomeAppContext : DataConnection
{
    public ITable<Category> Categories { get { return this.GetTable<Category>(); } }
    public ITable<Meeting> Meetings { get { return this.GetTable<Meeting>(); } }

    public SomeAppContext() : base("SomeAppContext")
    {
    }

    public SomeAppContext(string configuration) : base(configuration)
    {
    }
}

Example db call would be something like:

public bool IsMeetingConcluded(int meetingID)
{
    using (var context = new SomeAppContext())
    {
        var meeting = context.Meetings.Where(x => x.MeetingID == meetingID).FirstOrDefault();
        
        if(meeting!=null)
        { 
            if(DateTime.Today > meeting.EndDate)
            {
                return true;
            }
        }
        return false;
    }
}

What do I need to do to get Mini Profiler to work with the above code?

Thx


#2

In case someone else can benefit from this question, I am posting the solution that I found today.

  • If you haven’t already, add the linq2db NuGet package.

  • Another thing to do is to add AllowMultipleQuery setting to Global.asax.cs Application_Start():

    protected void Application_Start()
    {
        ...
        LinqToDB.Common.Configuration.Linq.AllowMultipleQuery = true;
    }
    
  • Also, I updated the context class to this, and now the views have in the profiler output the sql one liner showing time in ms, as well as the links to click and display all the sql query details as well as duplicates, etc.

    public class SomeAppContext : DataConnection
    {
        public ITable<Category> Categories { get { return this.GetTable<Category>(); } }
        public ITable<Meeting> Meetings { get { return this.GetTable<Meeting>(); } }
    
    #if !DEBUG
                    public DbDataContext() : base("SomeAppContext") { }
    #else
            public SomeAppContext() : base(GetDataProvider(), GetConnection()) { }
    
            private static IDataProvider GetDataProvider()
            {
                return new SqlServerDataProvider("", SqlServerVersion.v2008);
            }
    
            private static IDbConnection GetConnection()
            {
                LinqToDB.Common.Configuration.AvoidSpecificDataProviderAPI = true;
                var cs = ConfigurationManager.ConnectionStrings["SomeAppContext"].ConnectionString;
                var dbConnection = new SqlConnection(cs)
                {
                    ConnectionString = cs
                };
                return new ProfiledDbConnection(dbConnection, MiniProfiler.Current);
            }
    #endif
    
    }
    
  • Keep in mind you may need to use a different SqlServerDataProvider, mine is SqlServerVersion.v2008, but here is the enum of supported providers:

    namespace LinqToDB.DataProvider.SqlServer
    {
        public enum SqlServerVersion
        {
            v2000 = 0,
            v2005 = 1,
            v2008 = 2,
            v2012 = 3
        }
    }