Sortowanie wierszy w tabeli danych


146

Mamy dwie kolumny w a DataTable, tak:

COL1   COL2
Abc    5
Def    8
Ghi    3

Próbujemy posortować to datatablewedług COL2malejącej kolejności.

COL1            COL2
ghi             8
abc             4
def             3
jkl             1

Próbowaliśmy tego:

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

ale bez użycia a DataView, chcemy posortować DataTablesam, a nie DataView.

Odpowiedzi:


355

Obawiam się, że nie można łatwo utworzyć w miejscu rodzaju DataTable, tak jak brzmi to, jakbyś chciał.

Co możesz zrobić, to utworzyć nowy DataTable na podstawie DataView utworzonego na podstawie oryginalnego DataTable. Zastosuj dowolne rodzaje i / lub filtry, które chcesz w DataView, a następnie utwórz nowy DataTable z DataView przy użyciu metody DataView.ToTable :

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

Chcę, aby wartość rosła pod względem wartości ceny, która jest dziesiętna. jak to zrobić?
— Ranjith Kumar Nagiri

To podejście wydaje się dobre. Ale czy nie ma na to bezpośredniego sposobu? Dlaczego nie mają DataTable.sort („by”)?
— Steam

28
Dzięki. Warto zauważyć, że „occr desc” tutaj, „occr” to nazwa kolumny, „desc” oznacza „malejąco”.
— user1032613

22
To zadziałało dla mnie dataTable.DefaultView.Sort = "Col1, Col2, Col3". Trochę czysty kod.
— Sai

7
Podobnie jak @Sai, możesz bezpośrednio modyfikować DataTable.DefaultView.Sort. Nie ma potrzeby „wyłamywania” widoku i ponownego tworzenia tabeli.
— Jonny

40

To ci pomoże ...

DataTable dt = new DataTable();         
dt.DefaultView.Sort = "Column_name desc";
dt = dt.DefaultView.ToTable();

Wielkie umysły myślą podobnie. Miałem właśnie zamieścić to samo rozwiązanie po przeczytaniu @ JayR's.
— Drew Chapin

for Column_name, ponieważ byłem zdezorientowany, co było occr w rozwiązaniu Jaya Riggsa :)
— Thameem

Cudowne i łatwe rozwiązanie :)
— M. Fawad Surosh

25

Jego proste użycie. Wybierz funkcję.

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

I gotowe ...... Miłego kodowania


Zauważ, że jeśli, tak jak PO, jesteś zainteresowany tylko w sortowaniu aspektem tego i nie chce, aby filtrować wyniki, można określić ją tak: Select("", "CompanyName ASC").
— Tawab Wakil

20

Może poniższe wskazówki mogą pomóc:

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

Tutaj możesz również użyć innych zapytań wyrażeń Lambda.


14

Czy próbowałeś użyć Select(filterExpression, sortOrder)metody w DataTable? Zobacz tutaj przykład. Zwróć uwagę, że ta metoda nie posortuje tabeli danych w miejscu, jeśli tego właśnie szukasz, ale zwróci posortowaną tablicę wierszy bez korzystania z widoku danych.


13

Lub, jeśli możesz użyć DataGridView, możesz po prostu zadzwonić 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);
        }
    }
}

Co dałoby pożądany rezultat:

Widok debugera


@vidyasagar Nie ma problemu. Ponadto, jeśli odpowiedź jest cenna, na przyszłość należy ją zagłosować (na przykład moja?). A jeśli odpowiedzią jest odpowiedź „THE”, należy ją oznaczyć jako odpowiedź (na przykład, Jay's).
— Gustavo Mori

11
 table.DefaultView.Sort = "[occr] DESC";

Vidya chce posortować swój stół według occr w porządku malejącym. Co robi powyższy prosty kod. Robi dokładnie to, co pokazał Jay Riggs (zaakceptowana odpowiedź), z wyjątkiem tego, że jest to zrobione w jednej linii kodu.
— ivg

2
Sugestia polegała na ulepszeniu postu; w przyszłości umieść te informacje o kodzie w odpowiedzi. Bo to zwiększa szansę, że ktoś zagłosuje za postem lub nawet wybierze go jako odpowiedź.
— ΩmegaMan

5

Istnieją dwa sposoby sortowania danych

1) sortowanie samych danych i wypełnienie siatki:

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) domyślny widok sortowania, podobny do sortowania z nagłówkiem kolumny siatki:

DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
dt1.DefaultView.Sort = "ID DESC";
datagridview1.DataSource = dt1;

1
Dziękuję za odpowiedź. Twój sposób # 1 pomógł w moim przypadku: zdefiniowałem bardzo specjalny IComparer, więc aby go użyć, zrobiłem coś takiego:DataRow[] rows = dt.Rows.Cast<DataRow>().OrderBy(row => row.Field<string>("FIELD_NAME"), MyCustomComparer.Instance).ToArray();
— Aleksei

4

Okazuje się, że istnieje specjalny przypadek, w którym można to osiągnąć. Sztuczka polega na tym, że podczas budowania DataTable zebrać wszystkie wiersze na liście, posortować je, a następnie dodać. Ta sprawa właśnie się pojawiła.


3

// Mam nadzieję, że to ci pomoże ...

        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;

1

TL; DR

posługiwać się tableObject.Select(queryExpression, sortOrderExpression) wybierz posortowane dane

Kompletny przykład

Kompletny przykład roboczy - można przetestować w aplikacji konsolowej :

    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();
            }
        }
    }

Wynik

wynik


0

Spróbuj tego:

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) Musisz utworzyć nową tabelę DataTable sortedDT = new DataTable(). 2) Musisz użyć ImportRow(nie możesz dodać wiersza z innej tabeli)
— marbel82
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.