.NET 
: SQL  vs LINQ
    
    ![]()  | 
    Hoje vamos comparar consultas SQL com as respectivas consultas LINQ | 
A escolha entre usar uma consulta SQL ou uma consulta LINQ depende do contexto em que você está trabalhando e das suas preferências pessoais. A seguir veremos alguns exemplos de consultas LINQ e SQL mostrando as diferenças.
SQL (Structured Query Language):
LINQ (Language Integrated Query):
Se você estiver trabalhando exclusivamente com bancos de dados relacionais e desejar otimização de desempenho, consultas SQL podem ser mais adequadas. No entanto se você estiver desenvolvendo em uma linguagem de programação que suporta LINQ e desejar aproveitar a verificação de tipo e a integração com a linguagem, LINQ pode ser uma boa escolha.
A seguir para ilustrar vamos comparar algumas consultas LINQ com a respectiva consulta SQL
Os exemplos da 
LINQ mostrados a seguir pressupõem o uso do Entity Framework Core e um 
DbContext chamado 
db.
		using (var db = new SeuDbContext()) { // ... as consultas LINQ são definidas aqui ... }  | 
	
Codigo de todos os 
							registros da tabela Produto.var resultado = db.Set<Produto>().Select(x => x.Codigo).ToList();SELECT Codigo FROM Produto
Codigo, Descricao e 
							Preco de todos os registros da tabela 
							Produto, criando um novo objeto anônimo para 
							cada resultado.
								var resultado = db.Set<Produto>()
  .Select(x => new
  {
    x.Codigo,
    x.Descricao,
    x.Preco
  }).ToList();
							         SELECT Codigo, Descricao, Preco FROM Produto
							Produto.var resultado = db.Set<Produto>().ToList();SELECT * FROM Produto
Codigo e Descricao, e 
							também calcula um novo valor chamado 
							CustoTotal (multiplicando Estoque 
							por Custo), atribuindo um alias a essa 
							nova coluna no resultado.var resultado = db.Set<Produto>() .Select(x => new { x.Codigo, x.Descricao, CustoTotal = x.Estoque * x.Custo }).ToList();SELECT Codigo, Descricao, Estoque * Custo as CustoTotal FROM Produto
Produto onde a propriedade 
							Codigo é igual a "1001".var resultado = db.Set<Produto>() .Where(x => x.Codigo == "1001") .ToList();SELECT * FROM Produto WHERE Codigo = '1001'
Produto onde a propriedade 
							Descricao contém a substring "MIE". Isso é 
							geralmente traduzido para um operador LIKE 
							no SQL.var resultado = db.Set<Produto>() .Where(x => x.Descricao.Contains("MIE")) .ToList();SELECT * FROM Produto WHERE Nome LIKE '%MIE%'
Produto onde a propriedade 
							Descricao começa com a string "ABC". Isso é 
							traduzido para um operador LIKE com um 
							curinga no final no SQL.var resultado = db.Set<Produto>() .Where(x => x.Descricao.StartsWith("ABC")) .ToList();SELECT * FROM Produto WHERE Codigo LIKE 'ABC%'
Produto onde a propriedade 
							Descricao termina com a string "ABC". Isso é 
							traduzido para um operador LIKE com um 
							curinga no início no SQL.
								var resultado = db.Set<Produto>()
                        .Where(x => x.Descricao.EndsWith("ABC"))
                        .ToList();
SELECT * FROM Produto
WHERE Codigo LIKE '%ABC'
							Produto onde a 
							propriedade Codigo está contida no 
							array de strings arr. Isso é traduzido 
							para um operador IN no SQL.var arr = new string[] {"A001", "B001", "C001" }; var resultado = db.Set<Produto>() .Where(x => arr.Contains(x.Codigo)) .ToList();SELECT * FROM Produto WHERE Codigo IN ('A001', 'B001', 'C001')
Produto onde a parte da data da 
							propriedade DataCriacao está dentro do 
							intervalo especificado (de 01/01/2022 a 31/12/2022).var inicio = new DateTime(2022, 1, 1); var fim = new DateTime(2022, 12, 31); var resultado = db.Set<Produto>() .Where(x => x.DataCriacao.Date >= inicio && x.DataCriacao.Date <= fim) .ToList();SELECT * FROM Produto WHERE DataCriacao >= '2022-01-01' AND DataCriacao <= '2022-12-31'
Produto onde a 
							propriedade Custo é maior que 1000.var resultado = db.Set<Produto>() .Count(x => x.Custo > 1000);SELECT Count(*) FROM Produto WHERE Custo > 1000
Custo na tabela
							Produto.
								var resultado = db.Set<Produto>()
                        .Sum(x => x.Custo);
SELECT SUM(Custo) FROM Produto
							Custo na tabela 
							Produto.
								var resultado = db.Set<Produto>()
                          .Min(x => x.Custo);
SELECT MIN(Custo) FROM Produto
							Custo na tabela 
							Produto.var resultado = db.Set<Produto>() .Max(x => x.Custo);SELECT MAX(Custo) FROM Produto
Custo na 
							tabela Produto.var resultado = db.Set<Produto>() .Average(x => x.Custo);SELECT Average(Custo) FROM Produto
Produto pela propriedade
							Codigo em ordem crescente (padrão).var resultado = db.Set<Produto>() .OrderBy(x => x.Codigo) .ToList();SELECT * FROM Produto ORDER BY Codigo
Produto pela propriedade
							Codigo em ordem decrescente.var resultado = db.Set<Produto>() .OrderByDesc(x => x.Codigo) .ToList();SELECT * FROM Produto ORDER BY Codigo DESC
Produto primeiramente pela 
							propriedade Codigo (ascendente) e, em 
							seguida, pela propriedade Descricao 
							(ascendente) dentro dos grupos de Codigo.var resultado = db.Set<Produto>() .OrderBy(x => x.Codigo) .ThenBy(x => x.Descricao) .ToList();SELECT * FROM Produto ORDER BY Codigo, Descricao
Produto pela propriedade 
							Categoria e, para cada categoria, seleciona a 
							categoria e a soma dos custos dos produtos nessa 
							categoria.var resultado = db.Set<Produto>() .GroupBy(x => x.Categoria) .Select(x => new { Categoria = x.Key, CustoTotal = x.Sum(a => a.Custo) }).ToList();SELECT Categoria, SUM(Custo) as CustoTotal FROM Produto GROUP BY Categoria
Produto pelas propriedades 
							Categoria e Fornecedor, e para 
							cada combinação única, seleciona a categoria, o 
							fornecedor e a soma dos custos dos produtos nessa 
							combinação.var resultado = db.Set<Produto>() .GroupBy(x => new { x.Categoria, x.Fornecedor }) .Select(x => new { Categoria = x.Key, CustoTotal = x.Sum(a => a.Custo) }).ToList();SELECT Categoria, Fornecedor, SUM(Custo) as CustoTotal FROM Produto GROUP BY Categoria, Fornecedor
Codigo, 
							depois pula um certo número de registros (skip) 
							com base na página atual e no tamanho da página, e 
							finalmente pega um número específico de registros (take) 
							para exibir na página atual.var pagina = 3; var tamanho = 10; var skip = (pagina - 1) * tamanho; var take = tamanho; var resultado = db.Set<Produto>() .OrderBy(x => x.Codigo) .Skip(skip) .Take(take) .ToList();SELECT * FROM Produto ORDER BY Codigo OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
Pedido, Cliente 
							e Produto (assumindo que as 
							propriedades de navegação Cliente e
							Produto estão definidas na entidade
							Pedido). Ela seleciona a data da 
							transação do pedido, o nome do cliente e o código do 
							produto.var resultado = db.Set<Pedido>() .Select(x => new { x.DataTransacao, NomeCliente = x.Cliente.Nome, ProdutoCodigo = x.Produto.Codigo, x.Total }).ToList();SELECT s.DataTransacao, c.Nome as NomeCliente, p.Codigo as ProdutoCodigo FROM Pedido s LEFT JOIN Cliente c ON s.ClienteId = c.Id LEFT JOIN Produto p ON s.ProdutoId = p.Id
var inicio = new DateTime(2022, 1, 1); var fim = new DateTime(2022, 12, 31); var resultado = db.Set<Pedido>() .Where(x.DataTransacao >= inicio && x.DataTransacao <= fim) .GroupBy(x => new { NomeCliente = x.Cliente.Nome, ProdutoCodigo = x.Produto.Codigo }) .Select(x => new { NomeCliente = x.Key.NomeCliente, ProdutoCodigo = x.Key.ProdutoCodigo, TotalVendas = x.Sum(x.Total) }) .OrderBy(x => x.NomeCliente) .ThenByDescending(x => x.ProdutoCodigo) .ToList();SELECT c.Nome as NomeCliente, p.Codigo as ProdutoCodigo, SUM(s.Total) AS TotalVendas FROM Pedido s LEFT JOIN Cliente c ON s.ClienteId = c.Id LEFT JOIN Produto p ON s.ProdutoId = p.Id WHERE s.DataTransacao >= '2022-01-01' AND s.DataTransacao <= '2022-12-31' GROUP By c.Nome, p.Codigo ORDER BY c.Nome, p.Codigo DESC
Para consultas muito complexas envolvendo múltiplas junções e subconsultas, o SQL pode oferecer mais controle e potencial de otimização manual. No entanto, o EF Core tem evoluído bastante na tradução de LINQ para SQL eficiente.
E estamos 
conversados... 
"E disse-lhe Jesus: Em verdade te digo que hoje 
estarás comigo no Paraíso."
Lucas 23:43
Referências:
C# - Tasks x Threads. Qual a diferença
VB .NET - Datas, horas: conceitos e operações
C# - Programação Assíncrona como : Asycn e Task
O tratamento de datas no VB.NET - Macoratti.net
C# - Obtfimo a data e a hora por TimeZone
C# - O Struct Guid - Macoratti.net
C# - Checando Null de uma forma mais elegante
DateTime - Macoratti.net
Null o que é isso ? - Macoratti.net
Formatação de data e hora para uma cultura ...
C# - Calculando a diferença entre duas datas
NET - Padrão de Projeto - Null Object Pattern
C# - Fundamentos : Definindo DateTime como Null ...
C# - Os tipos Nullable (Tipos Anuláveis)