Resumo : neste tutorial, você aprenderá como usar o ExecuteSQLRaw()
método EF Core para executar uma instrução SQL bruta.
Introdução ao método ExecuteSQLRaw() do EF Core
O ExecuteSQLRaw()
método permite executar um SQL bruto e retornar o número de linhas afetadas. É útil quando você deseja:
- Execute uma
DELETE
instrução e retorne o número de linhas excluídas. - Execute uma
UPDATE
instrução e retorne o número de linhas atualizadas. - Execute um procedimento armazenado e retorne a linha afetada.
Observe que o ExecuteSQLRaw()
método não inicia uma transação. Para iniciar uma transação, você precisa primeiro usar UseTransaction
ou ligar BeginTransaction()
.
Para evitar a injeção de SQL, você nunca deve concatenar ou interpolar ($””) a consulta com valores não validados fornecidos pelo usuário para o ExecuteSQLRaw()
método.
Em vez disso, você pode incluir espaços reservados para parâmetros na string de consulta SQL e, em seguida, fornecer parâmetros como argumentos adicionais. Por exemplo:
var id = 1;
context.Database.ExecuteSqlRaw("DELETE FROM table WHERE Id={0}",id);
Linguagem de código: C# ( cs )
O ExecuteSQLRaw()
método converterá automaticamente os parâmetros em DbParamter
objetos.
Exemplos do método EF Core ExecuteSQLRaw()
Usaremos o projeto EF Core Sample para a demonstração. O seguinte mostra as tabelas Employees
e Departments
:
1) Usando ExecuteSQLRaw() para executar uma instrução DELETE
O exemplo a seguir usa o ExecuteSQLRaw()
método para excluir um funcionário com id 1:
using HR;
using static System.Console;
using Microsoft.EntityFrameworkCore;
using var context = new HRContext();
var sql = @"DELETE FROM employees WHERE id={0}";
var employeeId = 1;
var rowCount = context.Database.ExecuteSqlRaw(sql, employeeId);
WriteLine($"The number of row deleted {rowCount}");
Linguagem de código: C# ( cs )
Saída:
The number of row deleted 1
Linguagem de código: C# ( cs )
Nos bastidores, o EF Core parametrizou a consulta e a executou conforme mostrado no log a seguir:
-- [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
DELETE FROM employees WHERE id=@p0
Linguagem de código: C# ( cs )
O log mostra que o EF Core converteu o valor do id em um DbParameter
objeto.
2) Usando ExecuteSQLRaw() para executar uma instrução UPDATE
O exemplo a seguir ilustra como usar o ExecuteSQLRaw()
método para executar uma UPDATE
instrução que aumenta o salário para 5% do id do funcionário 2:
using HR;
using static System.Console;
using Microsoft.EntityFrameworkCore;
using var context = new HRContext();
var sql = @"UPDATE employees SET Salary=Salary*1.05 WHERE id={0}";
var employeeId = 2;
var rowCount = context.Database.ExecuteSqlRaw(sql, employeeId);
WriteLine($"The number of row updated {rowCount}");
Linguagem de código: C# ( cs )
Saída:
The number of row updated 1
Linguagem de código: C# ( cs )
O EF Core enviou a seguinte UPDATE
instrução ao banco de dados para execução:
-- prameters=[@p0='2'], CommandType='Text', CommandTimeout='30']
UPDATE employees SET Salary=Salary*1.05 WHERE id=@p0
Linguagem de código: C# ( cs )
3) Usando ExecuteSQLRaw() para executar um procedimento armazenado
Primeiro, adicione uma nova migração para criar um procedimento armazenado:
add-migration CreateDeleteDepartmentSP
Linguagem de código: C# ( cs )
Segundo, modifique a classe CreateDeleteDepartmentSP
no diretório Migrations para criar um procedimento armazenado que exclua um departamento por id no Up()
método e descarte o procedimento armazenado no Down()
método:
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace HR.Migrations;
/// <inheritdoc />
public partial class CreateDeleteDepartmentSP : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
var command = @"CREATE PROCEDURE DeleteDepartment(@Id AS INT)
AS
BEGIN
DELETE FROM Departments
WHERE Id=@Id;
END";
migrationBuilder.Sql(command);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
var command = @"DROP PROCEDURE DeleteDepartment;";
migrationBuilder.Sql(command);
}
}
Linguagem de código: C# ( cs )
Terceiro, crie o procedimento armazenado executando o Update-Database
comando no Console do Gerenciador de Pacotes:
Update-Database
Linguagem de código: C# ( cs )
Por fim, execute o procedimento armazenado para excluir o departamento com id 1:
using HR;
using static System.Console;
using Microsoft.EntityFrameworkCore;
using var context = new HRContext();
var sql = @"EXECUTE DeleteDepartment {0}";
var departmentId = 1;
var rowCount = context.Database.ExecuteSqlRaw(sql, departmentId);
WriteLine($"The number of row deleted {rowCount}");
Linguagem de código: C# ( cs )
Saída:
The number of row deleted 1
Linguagem de código: C# ( cs )
O EF Core enviou a instrução SQL ao banco de dados para executar o procedimento armazenado:
-- [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
EXECUTE DeleteDepartment @p0
Linguagem de código: C# ( cs )
Resumo
- Use o
ExecuteSQLRaw()
método para executar um SQL bruto e retornar o número de linhas afetadas.