170

We have two columns in a DataTable, like so:

COL1   COL2
Abc    5
Def    8
Ghi    3

We're trying to sort this datatable based on COL2 in decreasing order.

COL1            COL2
ghi             8
abc             4
def             3
jkl             1

We tried this:

ft.DefaultView.Sort = "COL2 desc";
ft = ft.DefaultView.ToTable(true);

but, without using a DataView, we want to sort the DataTable itself, not the DataView.

Behzad Ebrahimi
  • 992
  • 1
  • 16
  • 28
vidya sagar
  • 2,001
  • 3
  • 18
  • 18

14 Answers14

384

I'm afraid you can't easily do an in-place sort of a DataTable like it sounds like you want to do.

What you can do is create a new DataTable from a DataView that you create from your original DataTable. Apply whatever sorts and/or filters you want on the DataView and then create a new DataTable from the DataView using the DataView.ToTable method:

   DataView dv = ft.DefaultView;
   dv.Sort = "occr desc";
   DataTable sortedDT = dv.ToTable();
Jay Riggs
  • 53,046
  • 9
  • 139
  • 151
  • i want the value ascending in terms of price value which is decimal. how to do it? – Ranjith Kumar Nagiri Nov 26 '13 at 13:39
  • This approach seems fine. But is there no direct way of doing it ? Why don't they have a DataTable.sort("by") ? – Steam Jan 08 '14 at 19:59
  • 33
    Thanks. It's worth noting that, "occr desc" here, "occr" is the column name, "desc" means "descending". – WSBT Dec 18 '14 at 03:17
  • 26
    This worked for me dataTable.DefaultView.Sort = "Col1, Col2, Col3". Little clean code. – Sai Sep 18 '15 at 23:04
  • It works for sorting but If I want to replace my original table with the sorted one what should I do. So that when I access this table the second time it is still sorted. – مسعود Aug 01 '16 at 13:11
  • 7
    Just like @Sai, you can modify the DataTable.DefaultView.Sort directly. No need to "break out" the view and recreate a table. – Jonny Oct 20 '16 at 11:16
  • @Sai is the MAN! That little line of code just saved my sanity! – Johnny Bones Mar 27 '17 at 20:30
  • It works fine for me. If you need more benefit then you may initialize data to a session variable: "Session["nameTable"] = yourDataTable" and then use: "DataTable dt = (DataTable)Session["nameTable"]". Finally use above sorting code using "dt" DataTable instance. Thanks – Subarata Talukder Jan 06 '20 at 06:42
63

This will help you...

DataTable dt = new DataTable();         
dt.DefaultView.Sort = "Column_name desc";
dt = dt.DefaultView.ToTable();
Ankita_Shrivastava
  • 1,225
  • 11
  • 9
33

Its Simple Use .Select function.

DataRow[] foundRows=table.Select("Date = '1/31/1979' or OrderID = 2", "CompanyName ASC");
DataTable dt = foundRows.CopyToDataTable();

And it's done......Happy Coding

Abdul
  • 854
  • 1
  • 9
  • 11
  • 2
    Note that if, like OP, you are only interested in the sorting aspect of this and don't want to filter the results, you can specify it like this: `Select("", "CompanyName ASC")`. – Tawab Wakil May 04 '20 at 16:54
  • 1
    This is a fantastic answer. Allows the use of dynamically generated text strings for filtering and sorting! Glad I found this answer! – kenmtb Dec 02 '20 at 04:10
22

Maybe the following can help:

DataRow[] dataRows = table.Select().OrderBy(u => u["EmailId"]).ToArray();

Here, you can use other Lambda expression queries too.

Pang
  • 9,564
  • 146
  • 81
  • 122
Vishnu
  • 2,135
  • 2
  • 30
  • 51
14

Did you try using the Select(filterExpression, sortOrder) method on DataTable? See here for an example. Note this method will not sort the data table in place, if that is what you are looking for, but it will return a sorted array of rows without using a data view.

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
14

Or, if you can use a DataGridView, you could just call Sort(column, direction):

namespace Sorter
{
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.dataGridView1.Rows.Add("Abc", 5);
            this.dataGridView1.Rows.Add("Def", 8);
            this.dataGridView1.Rows.Add("Ghi", 3);
            this.dataGridView1.Sort(this.dataGridView1.Columns[1], 
                                    ListSortDirection.Ascending);
        }
    }
}

Which would give you the desired result:

Debugger view

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
  • @vidyasagar No problem. Also, for future reference, if an answer is valuable, you should vote it up (example, mine?). And if an answer is "THE" answer, you should mark it as the answer (example, Jay's). – Gustavo Mori Feb 02 '12 at 10:36
13
 table.DefaultView.Sort = "[occr] DESC";
ivg
  • 439
  • 4
  • 7
  • Vidya wants to sort his table by occr in desc order. Which the simple code above does. It does exactly what Jay Riggs (accepted answer) showed except this is done in one line of code. – ivg Feb 13 '15 at 20:51
  • 3
    The suggestion was to better the post; in the future place that information about the code into the response. For it betters the chance of someone upvoting the post or even selecting it as the answer. – ΩmegaMan Feb 14 '15 at 11:04
6

Use LINQ - The beauty of C#

DataTable newDataTable = baseTable.AsEnumerable()
                   .OrderBy(r=> r.Field<int>("ColumnName"))
                   .CopyToDataTable();
SOUVIK SAHA
  • 191
  • 2
  • 4
5

There is 2 way for sort data

1) sorting just data and fill into grid:

DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
DataTable dt2 = new DataTable(); // temp data table
DataRow[] dra = dt1.Select("", "ID DESC");
if (dra.Length > 0)
    dt2 = dra.CopyToDataTable();
datagridview1.DataSource = dt2;

2) sort default view that is like of sort with grid column header:

DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
dt1.DefaultView.Sort = "ID DESC";
datagridview1.DataSource = dt1;
Zolfaghari
  • 1,259
  • 1
  • 15
  • 14
  • 1
    Thanks for the answer. Your way #1 helped in my case: I got a very special IComparer defined, so to use it I did something like this: `DataRow[] rows = dt.Rows.Cast().OrderBy(row => row.Field("FIELD_NAME"), MyCustomComparer.Instance).ToArray();` – Aleksei May 31 '17 at 12:37
4

It turns out there is a special case where this can be achieved. The trick is when building the DataTable, collect all the rows in a list, sort them, then add them. This case just came up here.

Joshua
  • 40,822
  • 8
  • 72
  • 132
3

//Hope This will help you..

        DataTable table = new DataTable();
        //DataRow[] rowArray = dataTable.Select();
        table = dataTable.Clone();
        for (int i = dataTable.Rows.Count - 1; i >= 0; i--)
        {
            table.ImportRow(dataTable.Rows[i]);
        }
        return table;
Kumod Singh
  • 2,113
  • 1
  • 16
  • 18
2

TL;DR

use tableObject.Select(queryExpression, sortOrderExpression) to select data in sorted manner

Complete example

Complete working example - can be tested in a console application:

    using System;
    using System.Data;

    namespace A
    {
        class Program
        {
            static void Main(string[] args)
            {
                DataTable table = new DataTable("Orders");
                table.Columns.Add("OrderID", typeof(Int32));
                table.Columns.Add("OrderQuantity", typeof(Int32));
                table.Columns.Add("CompanyName", typeof(string));
                table.Columns.Add("Date", typeof(DateTime));

                DataRow newRow = table.NewRow();
                newRow["OrderID"] = 1;
                newRow["OrderQuantity"] = 3;
                newRow["CompanyName"] = "NewCompanyName";
                newRow["Date"] = "1979, 1, 31";

                // Add the row to the rows collection.
                table.Rows.Add(newRow);

                DataRow newRow2 = table.NewRow();
                newRow2["OrderID"] = 2;
                newRow2["OrderQuantity"] = 2;
                newRow2["CompanyName"] = "NewCompanyName1";
                table.Rows.Add(newRow2);

                DataRow newRow3 = table.NewRow();
                newRow3["OrderID"] = 3;
                newRow3["OrderQuantity"] = 2;
                newRow3["CompanyName"] = "NewCompanyName2";
                table.Rows.Add(newRow3);

                DataRow[] foundRows;

                Console.WriteLine("Original table's CompanyNames");
                Console.WriteLine("************************************");
                foundRows = table.Select();

                // Print column 0 of each returned row.
                for (int i = 0; i < foundRows.Length; i++)
                    Console.WriteLine(foundRows[i][2]);

                // Presuming the DataTable has a column named Date.
                string expression = "Date = '1/31/1979' or OrderID = 2";
                // string expression = "OrderQuantity = 2 and OrderID = 2";

                // Sort descending by column named CompanyName.
                string sortOrder = "CompanyName ASC";

                Console.WriteLine("\nCompanyNames data for Date = '1/31/1979' or OrderID = 2, sorted CompanyName ASC");
                Console.WriteLine("************************************");
                // Use the Select method to find all rows matching the filter.
                foundRows = table.Select(expression, sortOrder);

                // Print column 0 of each returned row.
                for (int i = 0; i < foundRows.Length; i++)
                    Console.WriteLine(foundRows[i][2]);

                Console.ReadKey();
            }
        }
    }

Output

output

Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
0

try this:

DataTable DT = new DataTable();
DataTable sortedDT = DT;
sortedDT.Clear();
foreach (DataRow row in DT.Select("", "DiffTotal desc"))
{
    sortedDT.NewRow();
    sortedDT.Rows.Add(row);
}
DT = sortedDT;
  • 1) You must create new table `DataTable sortedDT = new DataTable()`. 2) You need to use `ImportRow` (you can't add row from different table) – marbel82 May 26 '15 at 11:09
0

Yes the above answers describing the corect way to sort datatable

DataView dv = ft.DefaultView;
dv.Sort = "occr desc";
DataTable sortedDT = dv.ToTable();

But in addition to this, to select particular row in it you can use LINQ and try following

var Temp = MyDataSet.Tables[0].AsEnumerable().Take(1).CopyToDataTable();
Rush.2707
  • 685
  • 10
  • 29