🎯 Objetivo: Neste capítulo, você irá dominar o LINQ (Language-Integrated Query), uma das funcionalidades mais poderosas e elegantes do C#. LINQ permite que você escreva consultas a dados de forma unificada e segura, independentemente da fonte de dados, seja uma coleção em memória, um banco de dados, ou um arquivo XML.
Imagine que seu programa precisa fazer o seguinte:
<featured>.Antes do LINQ, você precisaria de três abordagens diferentes:
foreach com um if para a lista.string de consulta SQL ("SELECT * FROM Clientes WHERE Cidade = 'São Paulo'") que poderia conter erros de digitação e só seriam descobertos em tempo de execução.Essa inconsistência tornava o código difícil de ler, manter e propício a erros.
LINQ é uma sintaxe de consulta unificada que se integra diretamente à linguagem C#. Ela resolve o problema de forma elegante, permitindo que você use a mesma sintaxe para consultar qualquer tipo de fonte de dados, desde que haja um Provider (provedor) LINQ para ela.
O grande benefício é a segurança de tipos e a inteligência da IDE. Se você cometer um erro de sintaxe ou de nome de atributo na sua consulta LINQ, o compilador C# irá avisá-lo imediatamente, antes mesmo de você executar o programa.
Existem duas formas de escrever consultas LINQ. Ambas fazem a mesma coisa, mas uma pode ser mais legível que a outra, dependendo da sua preferência.
Sintaxe de Consulta (Query Syntax): É a sintaxe mais parecida com SQL, ideal para consultas mais simples e declarativas.
var resultado = from produto in listaDeProdutos
where produto.Preco > 500
select produto;
Sintaxe de Método (Method Syntax): É a sintaxe mais comum e flexível, que usa métodos de extensão e expressões lambda.
var resultado = listaDeProdutos.Where(produto => produto.Preco > 500);
Por baixo dos panos, o compilador C# converte a Sintaxe de Consulta para a Sintaxe de Método.
Vamos usar uma lista de produtos para ver o LINQ em ação.
// 1. Nossa fonte de dados: uma lista de objetos em memória
public class Produto
{
public int Id { get; set; }
public string Nome { get; set; }
public decimal Preco { get; set; }
public string Categoria { get; set; }
}
public class ExemploLinq
{
public static void Main(string[] args)
{
var produtos = new List<Produto>
{
new Produto { Id = 1, Nome = "Mouse", Preco = 120.00m, Categoria = "Periféricos" },
new Produto { Id = 2, Nome = "Teclado", Preco = 650.00m, Categoria = "Periféricos" },
new Produto { Id = 3, Nome = "Monitor", Preco = 1200.00m, Categoria = "Hardware" },
new Produto { Id = 4, Nome = "Webcam", Preco = 300.00m, Categoria = "Acessórios" },
new Produto { Id = 5, Nome = "SSD 1TB", Preco = 450.00m, Categoria = "Hardware" }
};
Console.WriteLine("--- Produtos com preço acima de R$500.00 ---");
// 2. Filtrando (where)
// Sintaxe de Consulta
var produtosCarosQuery = from p in produtos
where p.Preco > 500
select p;
// Sintaxe de Método
var produtosCarosMethod = produtos.Where(p => p.Preco > 500);
foreach (var p in produtosCarosMethod)
{
Console.WriteLine($"- {p.Nome} | R${p.Preco}");
}
Console.WriteLine("\n--- Nomes de produtos ordenados alfabeticamente ---");
// 3. Ordenando (orderby) e Projetando (select)
// Sintaxe de Consulta
var nomesOrdenadosQuery = from p in produtos
orderby p.Nome
select p.Nome;
// Sintaxe de Método
var nomesOrdenadosMethod = produtos.OrderBy(p => p.Nome).Select(p => p.Nome);
foreach (var nome in nomesOrdenadosMethod)
{
Console.WriteLine($"- {nome}");
}
Console.WriteLine("\n--- Produtos do tipo 'Hardware' ordenados por preço ---");
// 4. Combinando operações
// Sintaxe de Consulta
var hardwarePorPrecoQuery = from p in produtos
where p.Categoria == "Hardware"
orderby p.Preco descending
select p;
// Sintaxe de Método
var hardwarePorPrecoMethod = produtos
.Where(p => p.Categoria == "Hardware")
.OrderByDescending(p => p.Preco);
foreach (var p in hardwarePorPrecoMethod)
{
Console.WriteLine($"- {p.Nome} | R${p.Preco}");
}
}
}