- Instalar SDK .NET 9.0: https://dotnet.microsoft.com/download/dotnet/9.0
- Instalar ferramentas CLI de migrations do EF Core
dotnet tool install --global dotnet-ef- Subir instância postgres para teste
docker run -d --name postgres -e POSTGRES_PASSWORD=123456 -p 5432:5432 postgres:17- Executar aplicação
cd ConsoleApp
dotnet runSerá criado automaticamente o banco de dados "ef-core-playground".
Instruções sobre manipulação da base de dados com migrations. Use caso tenha alterado a estrutura de dados do exemplo.
Adicionar nova migration.
dotnet ef migrations add InicioAtualizar base de dados.
dotnet ef database updateRemover migrations e resetar base de dados.
dotnet ef database update 0
dotnet ef migrations removeC# Fluent LINQ Query
var query = conn.Fretes
.Where(x => x.Remetente.Cidade.UF == "SC")
.OrderByDescending(x => x.Valor)
.Select(x => new
{
x.Id,
x.Valor,
NomeRemetente = x.Remetente.Nome,
NomeDestinatario = x.Destinatario.Nome,
CidadeRemente = x.Remetente.Cidade.Nome,
CidadeDestinatario = x.Destinatario.Cidade.Nome
});
var fretes = query.AsNoTracking().ToList();Tradução SQL
SELECT f."Id", f."Valor", c."Nome" AS "NomeRemetente", c1."Nome" AS "NomeDestinatario", c0."Nome" AS "CidadeRemente", c2."Nome" AS "CidadeDestinatario"
FROM frete AS f
INNER JOIN cliente AS c ON f."RemetenteId" = c."Id"
INNER JOIN cidade AS c0 ON c."CidadeId" = c0."Id"
INNER JOIN cliente AS c1 ON f."DestinatarioId" = c1."Id"
INNER JOIN cidade AS c2 ON c1."CidadeId" = c2."Id"
WHERE c0."UF" = 'SC'
ORDER BY f."Valor" DESCC# Fluent LINQ Query
var query = conn.Fretes
.Where(x => x.Remetente.Cidade.UF == "SC")
.OrderByDescending(x => x.Valor)
.Select(x => new
{
x.Id,
x.Valor,
NomeRemetente = x.Remetente.Nome,
NomeDestinatario = x.Destinatario.Nome,
CidadeRemente = x.Remetente.Cidade.Nome,
CidadeDestinatario = x.Destinatario.Cidade.Nome
})
.Take(10) // << Adicionado
.Skip(30); // << Adicionado
var fretes = query.AsNoTracking().ToList();Tradução SQL
O ORM primeiro aplica uma query com o filtro UF = 'SC' com os mínimos join's necessários para resolver a condição, após isto limita os resultados e aplica os demais join's para obter os demais campos.
A query numa primeira visão parece maior que o necessário, mas está bem otimizada.
Também vale resaltar o cache de plano de execução do DB que torna rápida a analise do comando enviado e a seleção dos indices necessários para execução (Embora o PostgreSQL não tenha tal recurso, a performance dele é ótima).
SELECT s0."Id", s0."Valor", s0."Nome" AS "NomeRemetente", c1."Nome" AS "NomeDestinatario", s0."Nome0" AS "CidadeRemente", c2."Nome" AS "CidadeDestinatario"
FROM (
SELECT s."Id", s."DestinatarioId", s."Valor", s."Nome", s."Nome0"
FROM (
SELECT f."Id", f."DestinatarioId", f."Valor", c."Nome", c0."Nome" AS "Nome0"
FROM frete AS f
INNER JOIN cliente AS c ON f."RemetenteId" = c."Id"
INNER JOIN cidade AS c0 ON c."CidadeId" = c0."Id"
WHERE c0."UF" = 'SC'
ORDER BY f."Valor" DESC
LIMIT @__p_0
) AS s
ORDER BY s."Valor" DESC
OFFSET @__p_1
) AS s0
INNER JOIN cliente AS c1 ON s0."DestinatarioId" = c1."Id"
INNER JOIN cidade AS c2 ON c1."CidadeId" = c2."Id"
ORDER BY s0."Valor" DESC