Per realizzare applicazioni che rendano i nostri utenti entusiasti, non dobbiamo solo fare in modo che il nostro codice "funzioni" ma dovremmo anche garantire buone performance e pagine che si caricano rapidamente. Oltretutto, se realizziamo un'applicazione che esige poche risorse dal server, aiuteremo il nostro committente a ridurre i costi di funzionamento.
MiniProfiler è uno strumento che può aiutarci a realizzare questi obiettivi, perché serve a "profilare", cioè esaminare il comportamento della nostra applicazione per produrre un report HTML, compatto ma informativo, che rende evidenti le possibili inefficienze della nostra applicazione.
Con esso possiamo tracciare sia i tempi di esecuzione delle nostre routine che il numero di query SQL che inviamo al database.
Installare MiniProfiler
Iniziamo installando i pacchetti di MiniProfiler con i seguenti comandi. Il primo pacchetto è strettamente necessario, mentre il secondo lo referenziamo solo se nella nostra applicazione stiamo usando Entity Framework Core.dotnet add package MiniProfiler.AspNetCore.Mvc dotnet add package MiniProfiler.EntityFrameworkCore
Poi rechiamoci nel metodo Configure della classe Startup e configuriamo il middleware di MiniProfiler.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiniProfiler();
//Qui usiamo altri middleware
}Restiamo nella classe Startup e andiamo anche ad aggiungere i suoi servizi nel metodo ConfigureServices.
public void ConfigureServices(IServiceCollection services)
{
services.AddMiniProfiler()
.AddEntityFramework(); //Aggiungiamo questa riga solo se usiamo Entity Framework Core
//Qui aggiungiamo altri servizi
}MiniProfiler dispone di tante opzioni di configurazione che possiamo fornire al metodo AddMiniProfiler. Ad esempio possiamo decidere selettivamente quali richieste profilare e come vogliamo che siano mostrate le informazioni. Tutto ciò lo troviamo documentato all'indirizzo https://miniprofiler.com/dotnet/AspDotNetCore
Per completare l'installazione, apriamo la view /Views/Shared/_Layout.cshtml e inseriamo il tag helper di MiniProfiler, che verrà usato per sovraimporre il report HTML alle nostre view. Posizioniamolo subito prima della chiusura del tag .
<!DOCTYPE html>
<html>
<head>
<!-- Omissis -->
</head>
<body>
<!-- Omissis -->
<mini-profiler />
</body>
</html>Infine andiamo in /Views/_ViewImports.cshtml e registriamo il tag helper in modo che possa essere elaborato dal view engine Razor.
@addTagHelper *, MiniProfiler.AspNetCore.Mvc
Ora siamo finalmente pronti per iniziare a profilare la nostra applicazione ASP.NET Core.
Profilare le query LINQ di Entity Framework Core
Supponiamo di voler verificare il comportamento di una query LINQ che estre alcuni prodotti e da cui selezioniamo la categoria. Per profilare il codice, avvolgiamolo con l'istruzione MiniProfiler.Current.Step("Descrizione").using (MiniProfiler.Current.Step("Recupero categorie"))
{
var categories = new HashSet<Category>();
//db è un riferimento all'istanza del nostro DbContext
var products = await db.Products.Where(p => p.Amount > 1000)
.ToListAsync();
foreach (var product in products)
{
categories.Add(product.Category);
}
}Se abbiamo il lazy loading abilitato, questo codice produrrà numerose query al database: una per recuperare i prodotti e altre n per recuperare la categoria di ciascun prodotto. Questo è anche noto come problema Select n+1 e potrebbe passare inosservato se non prestassimo attenzione alle query inviate da Entity Framework Core. Con MiniProfiler, il problema risulta subito evidente perché nella ci mostra una linguetta nella parte alta a sinistra della pagina. Essa riporta il tempo di esecuzione con un punto esclamativo, a segnalare una situazione anomala. Lo possiamo cliccare per avere dettagli aggiuntivi e scoprire che in questo caso stiamo inviando ben 38 query SQL, come si nota dall'immagine.

Cliccando il 38 possiamo entrare nel dettaglio per scoprire quali sono le query in questione. Qui sono anche evidenti i momenti in cui apriamo e chiudiamo la connessione.

Comprendere il problema è solo il primo passo ma ci mette in condizione di pensare a una soluzione migliore, che in questo caso consiste nel modificare la query LINQ così.
var categories = await db.Products.Where(p => p.Amount > 1000) .Select(p => p.Category) .Distinct() .ToListAsync();
Profilare le query di ADO.NET
Anche usando ADO.NET possiamo sfruttare MiniProfiler per misurare il tempo di esecuzione delle query. Per attivare il profiler, in questo caso dobbiamo anche crearci un oggetto StackExchange.Profiling.Data.ProfiledDbConnection e passargli la connessione nel costruttore, come si vede nel seguente esempio.using (MiniProfiler.Current.Step("Query ADO.NET"))
{
using (var conn = new StackExchange.Profiling.Data.ProfiledDbConnection(
new SqlConnection(connString), MiniProfiler.Current))
{
await conn.OpenAsync();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT * FROM Products, Categories WHERE Products.Amount > 1000";
using (var reader = await cmd.ExecuteReaderAsync())
{
//Omissis
}
}
}
}In questo caso vediamo appunto che la query (una CROSS JOIN non corretta) sta richiedendo più di 1 secondo e quindi dovremmo valutare se abbiamo risultati migliori da una LEFT JOIN e dall'aggiunta di indici.

Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Usare la parola chiave field per semplificare la scrittura di proprietà in C#
Creare una cache temporanea in JavaScript
Cambiamenti in OpenAPI per la documentazione di ASP.NET
Welcome to Future Dev Day 2026
Permettere a un LLM di invocare funzioni con Microsoft.Extensions.AI
Creare una file based app con C#
Ottimizzare le API in ASP.NET con Feature Flags
Gestione opzioni colonna nella Blazor QuickGrid
Nuova modale riconnessione Blazor
Creare comandi nella dashboard .NET Aspire
Filtrare i dati in ASP.NET Core usando OpenTelemetry su Azure Monitor
Semplificare la gestione dei modelli con Azure AI Foundry Model Router
I più letti di oggi
- Effettuare il multi-checkout in linea nelle pipeline di Azure DevOps
- Accedere a risorse e immagini in Windows Store app di Windows 8
- Alleggerire le applicazioni WPF sfruttando gli oggetti Freezable
- Permettere il Drag-and-drop solo su zone predefinite con Silverlight 2.0
- Consumare dati binari in realtime lato client con ASP.NET Core SignalR
- Effetto turnstile su tutte le pagine con il Windows Phone Toolkit
- Personalizare l'icona e le funzionalità di un sito web per iOS e IE
- Caricamenti veloci da CDN e fallback locale con ASP.NET Core
- Utilizzare dati in formato XML in XAML
- Accedere a dati esposti con WebService con Silverlight 1.0


