MiniProfiler + Dapper + Entity Framework: logando instruções SQL em um projeto ASP.NET Core
Já abordei em outro artigo publicado neste blog o uso do MiniProfiler como solução para profiling/logging de instruções SQL, em um exemplo cobrindo as interações com um banco relacional geradas em uma aplicação ASP.NET Core que emprega Dapper no acesso a dados:
ASP.NET Core + Dapper + MiniProfiler: logging de instruções SQL sem complicações
Em uma live recente no Canal .NET retomei este assunto, refatorando o exemplo utilizado anteriormente de forma que pudesse descrever claramente as diferentes operações realizadas com Dapper num banco de dados do SQL Server ao longo de uma requisição HTTP. Demonstrei também o suporte oferecido pelo MiniProfiler ao Entity Framework Core. A gravação está disponível no YouTube e pode ser assistida gratuitamente:
Recomendo fortemente que você assista ao trecho do vídeo que aborda a utilização do MiniProfiler, a fim de entender todo o fluxo de profiling e logging envolvendo esta aplicação de exemplo.
O exemplo (uma API REST) em questão já foi disponibilizado no GitHub:
Para ativar o MiniProfiler (cujo uso deve ser evitado em um ambiente de Produção) em conjunto com Dapper, Entity Framework Core e SQL Server adicionei a esta API REST de exemplo os packages:
- MiniProfiler.AspNetCore.Mvc
- MiniProfiler.EntityFrameworkCore
No arquivo APIRegioes.csproj podemos observar esses e outros packages adicionados ao projeto:
Além de invocar a operação AddMiniProfiler (linha 22) no arquivo Program.cs, foi também acionado o método AddEntityFramework (linha 23) de forma a configurar o uso do MiniProfiler. Sua ativação dependerá ainda de uma chamada a UseMiniProfiler (linha 37). Em todos esses casos há uma checagem determinando se a execução está acontecendo em ambiente de Desenvolvimento, de forma a desabilitar o MiniProfiler num eventual ambiente de Produção:
Algumas das rotas possíveis para este projeto estão listadas na próxima imagem, exemplificando assim o logging de requisições HTTP em que se deu o uso do Entity Framework e de 2 alternativas baseadas em Dapper:
As classes utilizadas pelo Dapper e pelo Entity Framework Core representando regiões geográficas e estados têm sua definição na listagem a seguir:
A seguir temos a implementação do tipo RegioesContext, que corresponde à classe de contexto para uso do Entity Framework Core no acesso à base de dados:
Na imagem seguinte estão os logs e o profiling gerados durante uma requisição servida por este Controller, incluindo os tempos de processamento ao longo dos diferentes passos:
As interações com Dapper ocorrerão por meio da classe RegioesRepository, com uma instância de ProfiledDbConnection manipulando a conexão com o SQL Server em ambiente de Desenvolvimento (método GetConnection, linha 28):
- É justamente o tipo ProfiledDbConnection (namespace StackExchange.Profiling.Data) que permite efetuar o profiling/logging de instruções SQL utilizando Dapper ou diretamente ADO.NET;
- Enquanto o método Get envolve uma única instrução SQL de consulta, sua versão equivalente representada por GetV2 resultará em múltiplas queries durante o tempo de vida de uma requisição HTTP (uma consulta a regiões, além de queries subsequentes para cada região encontrada).
A classe RegioesDapperController fará uso do método Get de RegioesRepository durante o processamento de requisições HTTP:
Podemos observar no profiling correspondente a presença de uma única consulta à base de dados:
Já a classe RegioesDapperV2Controller utilizará o método GetV2 de RegioesRepository ao processar solicitações HTTP:
Conforme mencionei, múltiplas consultas à base poderão acontecer durante uma requisição direcionada a este Controller: