Resumo : neste tutorial, você aprenderá sobre o fluxo de consulta do EF Core e como consultar dados do banco de dados.
Fluxo de consulta do EF Core
O EF Core usa LINQ para consultar dados do banco de dados. Este é o fluxo de consulta quando você executa uma consulta:
Primeiro, você executa uma consulta:
context.Departments.ToList()
Linguagem de código: CSS ( css )
Em segundo lugar, o EF Core lê o modelo (classe Department) e trabalha com o provedor de dados (SQL Server neste exemplo) para construir uma instrução SQL correspondente:
SELECT [d].[Id], [d].[Name]
FROM [Departments] AS [d]
Linguagem de código: CSS ( css )
Como usamos o provedor de dados SQL Server, o EF Core irá gerar o T-SQL, que é um dialeto SQL do SQL Server.
Terceiro, o EF Core envia a instrução SQL gerada ao banco de dados para execução.
Quarto, o EF Core recebe os resultados tabulares do servidor de banco de dados.
Quinto, o EF Core materializa os resultados como objetos de Departamento
Por fim, o EF Core adiciona detalhes de rastreamento à instância DbContext.
O EF Core usa métodos e operadores LINQ para consultar dados. Por exemplo, o seguinte usa o método LINQ para obter todos os departamentos:
var departments = context.Departments.ToList();
Linguagem de código: JavaScript ( javascript )
e o exemplo a seguir usa operadores:
var departments = (from d
in context.Departments
select d)
.ToList();
Linguagem de código: JavaScript ( javascript )
Consulta um elemento que pode ser composto
As consultas são combináveis, permitindo dividir uma consulta complexa em partes. Por exemplo, você pode fazer isso quebrando a seguinte consulta:
var departments = context.Departments.ToList();
Linguagem de código: JavaScript ( javascript )
no seguinte:
var query = context.Departments;
var departments = query.ToList();
Linguagem de código: JavaScript ( javascript )
Enumeração de consulta
A consulta a seguir retorna todos os departamentos da tabela Departamentos de uma só vez:
var departments = context.Departments.ToList();
Linguagem de código: JavaScript ( javascript )
Isso significa que o EF Core recupera os dados e fecha a conexão com o banco de dados imediatamente.
No entanto, o seguinte só obtém os dados quando o loop for é executado e fecha a conexão com o banco de dados até que a última linha seja buscada:
using HR.Data;
using static System.Console;
var context = new HRContext();
var departments = context.Departments;
foreach (var d in departments)
{
WriteLine($"{d.Id} {d.Name}");
}
Linguagem de código: PHP ( php )
Se a enumeração for rápida, você ficará bem. No entanto, se a enumeração demorar, a conexão com o banco de dados permanecerá aberta até que a última linha seja buscada. Isso criará um problema de desempenho.
Portanto, é uma boa prática obter os resultados primeiro usando o método ToList().
Filtrando dados (WHERE)
Por padrão, o EF Core protege você contra injeção de SQL parametrizando consultas. O exemplo a seguir ilustra como consultar departamentos cujo nome é Vendas:
using HR.Data;
using static System.Console;
var context = new HRContext();
var departments = context.Departments
.Where(d => d.Name == "Sales")
.ToList();
foreach (var d in departments)
{
WriteLine($"{d.Id} {d.Name}");
}
Linguagem de código: JavaScript ( javascript )
Aqui está o SQL gerado que o EF Core envia para o banco de dados:
SELECT [d].[Id], [d].[Name]
FROM [Departments] AS [d]
WHERE [d].[Name] = N'Sales'
Linguagem de código: PHP ( php )
Quando você usa valores codificados como a string literal “Sales”, o EF Core não parametriza a consulta, o que não é seguro e vulnerável à injeção de SQL.
Porém, quando você usa uma variável e a passa para a consulta, o EF Core sempre criará parâmetros para o valor. Por exemplo:
using HR.Data;
using static System.Console;
var context = new HRContext();
var name = "Sales";
var departments = context.Departments
.Where(d => d.Name == name)
.ToList();
foreach (var d in departments)
{
WriteLine($"{d.Id} {d.Name}");
}
Linguagem de código: JavaScript ( javascript )
Neste exemplo, usamos a variável name na consulta em vez de usar valores literais. Se você executar o programa, verá que o EF Core parametriza a consulta da seguinte forma:
Executed DbCommand (64ms) [Parameters=[@__name_0='Sales' (Size = 4000)], CommandType='Text', CommandTimeout='30']
SELECT [d].[Id], [d].[Name]
FROM [Departments] AS [d]
WHERE [d].[Name] = @__name_0
Linguagem de código: PHP ( php )
A saída mostra que o EFCore cria um parâmetro chamado @__name_0 e o passa para a consulta. Portanto, você nunca deve passar os valores codificados para a consulta para evitar injeções de SQL.
Filtrando textos parciais (LIKE)
SQL possui o operador LIKE que permite combinar texto usando caracteres curinga%. Por exemplo, “%abc%” corresponderá a qualquer texto que contenha a string “abc”.
Para formar o operador LIKE no EF Core, você pode usar o método Like():
EF.Functions.Like(property, %keyword%)
Linguagem de código: CSS ( css )
Por exemplo, o seguinte usa o método Like() para localizar departamentos cujos nomes contêm a letra i:
using System.Data;
using static System.Console;
using Microsoft.EntityFrameworkCore;
using HR.Data;
var context = new HRContext();
var keyword = "i";
var departments = context.Departments
.Where(d => EF.Functions.Like(d.Name, $"%{keyword}%"))
.ToList();
foreach (var d in departments)
{
WriteLine($"{d.Id} {d.Name}");
}
Linguagem de código: JavaScript ( javascript )
Saída:
2 Marketing
3 Logistics
5 IT
Se você ativar o log, verá a seguinte instrução SQL:
Executed DbCommand(35ms) [Parameters=[@__Format_1='%i%' (Size = 4000)], CommandType = 'Text', CommandTimeout = '30']
SELECT[d].[Id], [d].[Name]
FROM[Departments] AS[d]
WHERE[d].[Name] LIKE @__Format_1
Linguagem de código: PHP ( php )
Encontrar uma entidade pelo seu valor chave
Para encontrar uma entidade por seu valor de chave, você usa DbSet.Find(key). Não que Find() seja o método DbSet() que é executado imediatamente assim que você o chama.
O exemplo a seguir usa o método Find() para obter o departamento por id:
using static System.Console;
using HR.Data;
var context = new HRContext();
var department = context.Departments.Find(1);
WriteLine($"{department?.Id} {department?.Name}");
Linguagem de código: JavaScript ( javascript )