110

I have a DataTable with a Name column. I want to generate a collection of the unique names ordered alphabetically. The following query ignores the order by clause.

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

Why does the orderby not get enforced?

Philip Raath
  • 440
  • 3
  • 17
Bob
  • 90,304
  • 29
  • 114
  • 125

7 Answers7

56

The problem is that the Distinct operator does not grant that it will maintain the original order of values.

So your query will need to work like this

var names = (from DataRow dr in dataTable.Rows
             select (string)dr["Name"]).Distinct().OrderBy( name => name );
DeadlyChambers
  • 4,627
  • 3
  • 39
  • 56
Bob
  • 90,304
  • 29
  • 114
  • 125
39

To make it more readable and maintainable, you can also split it up into multiple LINQ statements.

  1. First, select your data into a new list, let's call it x1, do a projection if desired
  2. Next, create a distinct list, from x1 into x2, using whatever distinction you require
  3. Finally, create an ordered list, from x2 into x3, sorting by whatever you desire
Paul Fleming
  • 22,772
  • 8
  • 65
  • 107
a7drew
  • 7,649
  • 5
  • 34
  • 39
11
var sortedTable = (from results in resultTable.AsEnumerable()
select (string)results[attributeList]).Distinct().OrderBy(name => name);
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
8

Try out the following:

dataTable.Rows.Cast<DataRow>().select(dr => dr["Name"].ToString()).Distinct().OrderBy(name => name);
Patrick D'Souza
  • 3,371
  • 2
  • 19
  • 37
Gavin Fang
  • 357
  • 5
  • 7
3

Try the following

var names = (from dr in dataTable.Rows
             select (string)dr["Name"]).Distinct().OrderBy(name => name);

this should work for what you need.

Sid M
  • 4,268
  • 4
  • 27
  • 47
Nick Berardi
  • 52,504
  • 14
  • 109
  • 135
2

To abstract: all of the answers have something in common.

OrderBy needs to be the final operation.

Philip Raath
  • 440
  • 3
  • 17
2

You can use something like that:

dataTable.Rows.Cast<DataRow>().GroupBy(g => g["Name"]).Select(s => s.First()).OrderBy(o => o["Name"]);
Presto
  • 806
  • 9
  • 24