2

I am getting an output from a DataTable for certain columns that have been defined in a string array: string[] columnsToBeUnique;

var ordered = dataTable1
                .AsEnumerable()
                .Select(column => columnsToBeUnique.Select(name => column[name]))
                .Order()
                .ToArray()
                ;

Without the .Order() I am getting the desired output. The the output however is not ordered so I want to order the output. When I add the .Order(), an error Failed to compare two elements in the array. is thrown.

I also tried:

var ordered = dataTable1
                .AsEnumerable()
                .Select(column => columnsToBeUnique.Select(name => column[name]))
                .OrderBy(x=>x)
                .ToList();

What am I doing wrong?

4
  • When you use AsEnumerable(), the item in the Select() call is a row, not a column. Additionally, you should probably also skip the ToList()/ToArray() call, and just keep the result as an Enumerable until you really need the array or list. Commented Apr 3 at 14:56
  • @JoelCoehoorn, if I skip whatever comes after the select. then I still have an unsorted output... Commented Apr 3 at 15:00
  • How do you want the results ordered? What column(s) decide this? Commented Apr 3 at 15:07
  • @JoelCoehoorn, ideally I want the sorting done on the columns in my columnsToBeUnique array. If I have 3 columns defined in my array, then first, second and then third... Commented Apr 3 at 15:13

1 Answer 1

3

The error message you're getting is because the object you're trying to order is an IEnumerable<object> (or similar) and .NET doesn't know how to compare two sequences by default.

You are selecting a sequence of values per row (via columnsToBeUnique.Select(...)), which results in an IEnumerable<object> per row. But IEnumerable<object> doesn't implement IComparable so .Order() or .OrderBy(x => x) doesn't know how to sort it.

Solve this by using a similar type:

Join the values into a String:

var ordered = dataTable1
    .AsEnumerable()
    .Select(row => string.Join("|", columnsToBeUnique.Select(col => row[col]?.ToString())))
    .OrderBy(x => x)
    .ToList();

Use ValueTuple if you know how many columns:

var ordered = dataTable1
    .AsEnumerable()
    .Select(row => (
        columnsToBeUnique.Length > 0 ? row[columnsToBeUnique[0]] : null,
        columnsToBeUnique.Length > 1 ? row[columnsToBeUnique[1]] : null,
        columnsToBeUnique.Length > 2 ? row[columnsToBeUnique[2]] : null
    ))
    .OrderBy(x => x)
    .ToList();

The second solution would only work if columnsToBeUnique has a fixed number of columns.

Sign up to request clarification or add additional context in comments.

2 Comments

That did the trick! Thanks. (The number of columns are not know so the first solved the issue)
@RicoStrydom Glad to hear! You are welcome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.