Trabalhando com DataTable via LINQ: do iniciante ao mestre em 20 minutos
\n\nImagine a situação: você está escrevendo um aplicativo em C#, carregando dados do banco em um DataTable, e então… precisa filtrar linhas por uma condição complexa, agrupar por data ou unir duas tabelas. O bom e velho DataTable.Select("...") com seus filtros de string quebra na segunda condição, e os loops foreach transformam o código em espaguete.
Familiar? Então bem-vindo ao mundo das consultas LINQ para DataTable. Esta é a sua super ferramenta, que transforma o trabalho com dados tabulares em código elegante, legível e poderoso. Neste guia, abordaremos tudo: desde o básico Where até os avançados Join e GroupBy. Vamos lá!
\n\n
O que é LINQ to DataSet e por que você precisa dele?
\n\nLINQ (Language Integrated Query) é uma linguagem de consulta integrada ao C#. Sua principal vantagem: você escreve consultas para qualquer tipo de dado (arrays, listas, XML, bancos de dados) da mesma forma — usando os operadores familiares from, where, select.
Mas com DataTable há um detalhe: o LINQ não pode ser aplicado diretamente a ele. DataTable não implementa a interface IEnumerable<T>. A solução é o método AsEnumerable(), que transforma a tabela em uma coleção de objetos DataRow. É com ela que o LINQ trabalha.
Vantagens da abordagem:
\n- \n
- ✅ Segurança de tipos: o compilador detecta erros nos nomes das colunas \n
- ✅ Legibilidade: o código se parece com SQL, mas continua sendo C# \n
- ✅ Poder: filtragem, projeção, agrupamento, ordenação — em uma única linha \n
- ✅ Desempenho: execução adiada (não carrega dados desnecessários) \n
Vamos direto ao ponto. Adicione no projeto uma referência a System.Data.DataSetExtensions (geralmente já existe) — e vamos em frente.
\n\n
Preparação dos dados: nossa tabela de teste
\n\nPara não ficarmos apenas na teoria, vamos criar um DataTable com dados de produtos. O código abaixo é a base para todos os exemplos:
// 1. Criando a tabela com colunas\nDataTable products = new DataTable("Products");\nproducts.Columns.Add("Id", typeof(int));\nproducts.Columns.Add("Name", typeof(string));\nproducts.Columns.Add("Category", typeof(string));\nproducts.Columns.Add("Price", typeof(decimal));\nproducts.Columns.Add("DateAdded", typeof(DateTime));\n\n// 2. Adicionando linhas\nproducts.Rows.Add(1, "Notebook ASUS", "Eletrônicos", 55000, DateTime.Now.AddDays(-10));\nproducts.Rows.Add(2, "Mouse Logitech", "Eletrônicos", 2500, DateTime.Now.AddDays(-5));\nproducts.Rows.Add(3, "Livro 'C# in Depth'", "Livros", 1800, DateTime.Now.AddDays(-2));\nproducts.Rows.Add(4, "Fone Sony", "Eletrônicos", 12000, DateTime.Now.AddDays(-1));\nproducts.Rows.Add(5, "Caderno Moleskine", "Papelaria", 1200, DateTime.Now.AddDays(-20));\nproducts.Rows.Add(6, "Caneta Parker", "Papelaria", 3500, DateTime.Now.AddDays(-15));\nproducts.Rows.Add(7, "Monitor Dell", "Eletrônicos", 32000, DateTime.Now.AddDays(-30));\n\nAgora temos 7 produtos. Hora de aplicar a mágica do LINQ.
\n\n\n\n
Consultas LINQ básicas para DataTable
\n\n1. Filtragem (Where) — como SQL WHERE
\n\nSuponha que você precise selecionar todos os produtos com preço acima de 10.000 reais. Sem LINQ, você escreveria um loop com verificação de row["Price"]. Com LINQ, fica assim:
var expensiveProducts = products.AsEnumerable()\n .Where(row => row.Field<decimal>("Price") > 10000);\n\nforeach (var row in expensiveProducts)\n{\n Console.WriteLine($"{row["Name"]} - {row["Price"]} reais.");\n}\n// Saída: Notebook ASUS - 55000, Fone Sony - 12000, Monitor Dell - 32000\n\nPonto importante: use o método Field<T>("ColumnName") em vez da conversão direta (decimal)row["Price"]. Isso é mais seguro: se a coluna for DBNull, Fie