Como Obter uma Lista Distinta e Ordenada de Nomes de um DataTable com LINQ

Usar LINQ para manipular dados de um DataTable pode ser bastante poderoso, mas também pode levar a resultados inesperados se não for tratado corretamente. Neste post do blog, vamos explorar um problema comum: gerar uma lista ordenada de nomes únicos de um DataTable. Vamos investigar por que uma consulta simples pode não fornecer a ordem esperada e apresentar uma solução estruturada.

O Problema

Você possui um DataTable contendo uma coluna para nomes, e deseja extrair uma coleção distinta desses nomes, ordenada alfabeticamente. Uma consulta LINQ típica se parece com isto:

var names =
    (from DataRow dr in dataTable.Rows
    orderby (string)dr["Name"]
    select (string)dr["Name"]).Distinct();

À primeira vista, isso parece correto, mas você pode notar que a cláusula orderby não impõe a ordenação esperada no resultado final. Por que isso acontece?

Entendendo o Problema

Quando você usa o método Distinct() após a ordenação, isso pode frequentemente levar a confusão. O processo de obter valores distintos é separado de como os valores são ordenados.

Por que a Ordenação Pode Não Funcionar

  • O método Distinct() pode não manter a ordem estabelecida pelo orderby. Quando ele processa os dados, ele se concentra apenas nos valores distintos, sem reter a ordem.

Para alcançar tanto a distinção quanto a ordem, precisamos ajustar nossa abordagem com LINQ.

Uma Solução Estruturada

Para garantir que você obtenha tanto nomes distintos quanto ordenados, você pode dividir o processo em três etapas claras:

Etapa 1: Selecionar Nomes em uma Nova Lista

Primeiro, reúna todos os nomes em uma coleção. Você pode fazer uma projeção durante esta etapa, se necessário.

var x1 = 
    (from DataRow dr in dataTable.Rows
    select (string)dr["Name"]).ToList();

Etapa 2: Criar uma Lista Distinta

Em seguida, crie uma lista distinta a partir da coleção obtida na Etapa 1. Esta etapa filtrará os duplicados.

var x2 = x1.Distinct().ToList();

Etapa 3: Criar uma Lista Ordenada

Por fim, pegue a lista distinta e ordene-a alfabeticamente.

var orderedNames = x2.OrderBy(name => name).ToList();

Exemplo Completo de Código

Veja como o código completo se parece quando colocado junto:

var x1 = 
    (from DataRow dr in dataTable.Rows
    select (string)dr["Name"]).ToList();

var x2 = x1.Distinct().ToList();

var orderedNames = x2.OrderBy(name => name).ToList();

Conclusão

Ao dividir a consulta LINQ em várias partes, podemos obter efetivamente uma lista distinta de nomes de um DataTable que também está ordenada alfabeticamente. Este método melhora tanto a legibilidade quanto a manutenibilidade do seu código, garantindo que cada etapa do processo seja clara e lógica.

Essa abordagem estruturada garante que você extraia os nomes únicos na ordem desejada, tornando-a uma solução confiável em seus projetos de desenvolvimento em C#.

Sinta-se à vontade para experimentar este método e veja como ele funciona para suas necessidades de dados!