Raw SQL Queries no Entity Framework

No Entity Framework, normalmente usamos o LINQ para consultas ao banco de dados. No entanto, em situações que exigem maior controle ou quando precisamos utilizar funcionalidades específicas do banco de dados, podemos recorrer às “Raw SQL Queries” (consultas SQL brutas). Essas consultas permitem escrever SQL puro, utilizando sintaxes específicas, otimizando a performance de consultas complexas e aproveitando funcionalidades que não são facilmente replicáveis pelos métodos convencionais do Entity Framework.

Executando consultas com tipos mapeados

Uma das principais aplicações de consultas SQL brutas é executar comandos SELECT diretamente, mapear os resultados para entidades ou tipos personalizados e integrá-los ao contexto do EF. Para executar uma consulta SQL que retorna resultados e mapear esses resultados para uma entidade do EF:

				
					var products = dbContext.Products
   	 .FromSqlRaw("SELECT * FROM Products WHERE Price > {0}", 100)
    	.ToList();
				
			

Aqui, “FromSqlRaw” permite que você insira uma consulta SQL diretamente. O {0} é um marcador de posição que será substituído pelo valor passado como argumento.

Ao usar consultas SQL brutas para mapear resultados para entidades do Entity Framework, é fundamental garantir que a estrutura do resultado da consulta seja equivalente à estrutura da entidade. Isso significa que as colunas retornadas pela consulta devem corresponder aos nomes e tipos das propriedades da entidade. Caso contrário, você pode encontrar erros ou resultados inesperados ao mapear os dados retornados para a entidade.

Executando comandos

Além de consultas SELECT, você pode usar SQL bruto para executar comandos que não retornam resultados, como INSERT, UPDATE ou DELETE:

				
					dbContext.Database
    .ExecuteSqlRaw("DELETE FROM Usuarios WHERE Id = {0}", "3");

				
			

O método “ExecuteSqlRaw” é usado para executar comandos SQL que alteram dados no banco de dados sem retornar um conjunto de resultados.

Parâmetros em consultas SQL

Para evitar problemas de segurança, como injeção de SQL, é crucial usar parâmetros nomeados ao construir consultas SQL. O Entity Framework fornece suporte para passar parâmetros de maneira segura.

				
					var categoryIdParam = new SqlParameter("@CategoryId", 1);
var products = dbContext.Products
    .FromSqlRaw("SELECT * FROM Products WHERE CategoryId = @CategoryId", categoryIdParam)
    .ToList();

				
			

Aqui, o “SqlParameter” é usado para passar um parâmetro para a consulta, garantindo que o valor seja corretamente escapado e prevenindo injeções SQL.

Passando múltiplos parâmetros

Se precisar passar mais de um parâmetro, você pode criar múltiplos objetos “SqlParameter” e passá-los como argumentos adicionais. Por exemplo:

				
					var categoryIdParam = new SqlParameter("@CategoryId", 1);
var minPriceParam = new SqlParameter("@MinPrice", 50);

var products = dbContext.Products
 .FromSqlRaw("SELECT * FROM Products WHERE CategoryId = @CategoryId AND Price > @MinPrice", categoryIdParam, minPriceParam)
    	.ToList();
				
			

Neste exemplo, dois parâmetros, @CategoryId e @MinPrice, são passados para a consulta. Cada parâmetro é criado como um objeto “SqlParameter” separado e, em seguida, ambos são incluídos na chamada para “FromSqlRaw”. Isso assegura que os valores sejam devidamente repassados, prevenindo possíveis injeções SQL e mantendo a segurança da aplicação.

Retornando tipos não mapeados

Outra funcionalidade poderosa do Entity Framework 8 é a capacidade de retornar tipos não mapeados diretamente a partir de consultas SQL brutas. Se você deseja retornar um tipo específico, como um DTO (ProductSummary), ao invés de entidades completas, utilize o método SqlQuery no contexto do banco de dados.

				
					var productSummaries = await dbContext.Database
    .SqlQuery<ProductSummary>(
        """
        SELECT
            p.Id as ProductId,
            p.Name,
            p.Price
        FROM dbo.Products p
        WHERE p.Price > @MinPrice
        """,
        new SqlParameter("@MinPrice", 50)
    )
    .ToListAsync();
				
			

Aqui, “ProductSummary” é um tipo não mapeado que representa um conjunto específico de colunas da tabela “Products”. Ao usar “SqlQuery”, você retorna apenas os dados necessários e otimiza a performance e evita o carregamento  da entidade completa.

Stored Procedures

Consultas SQL brutas são também úteis para executar stored procedures. Para detalhes sobre como executar stored procedures, consulte o artigo que em que abordamos esse tema clicando aqui.

Acelere a sua carreira conosco!

Se você é Desenvolvedor .NET Júnior e quer acelerar sua carreira até nível Pleno com salário de R$7k+, ou mesmo busca a primeira vaga, conheça a Mentoria .NET StartClique aqui

Se é Desenvolvedor .NET Pleno ou Sênior e quer virar referência técnica em sua equipe e mercado, com salário de R$10k+, conheça a Mentoria .NET ExpertClique aqui

Conclusão

Raw SQL Queries no Entity Framework oferecem uma flexibilidade significativa para lidar com consultas complexas e operações específicas do banco de dados que não são facilmente expressas através da API LINQ. Ao utilizar consultas SQL brutas, os desenvolvedores podem obter um controle mais granular e otimizado sobre as interações com o banco de dados.