Consulta principal do EF

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_0Linguagem 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_1Linguagem 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 )

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *