在数据表中对行进行排序

171

我们在一个 DataTable 中有两列,就像这样:

COL1   COL2
Abc    5
Def    8
Ghi    3

我们正在尝试根据 COL2 以降序排序此 datatable

COL1            COL2
ghi             8
abc             4
def             3
jkl             1

我们尝试了这个:

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

但是,不使用 DataView,我们想要对 DataTable 本身进行排序,而不是 DataView

14个回答

385

很抱歉,您无法轻易地对DataTable进行原地排序,就像您想要做的那样。

您可以从原始DataTable创建一个DataView,然后创建一个新的DataTable来自DataView,应用所需的任何排序和/或过滤器。使用DataView.ToTable 方法从DataView中创建一个新的DataTable:

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

我希望按价格升序排列其十进制数值。如何做到? - Ranjith Kumar Nagiri
这种方法看起来不错。但是没有直接的方法吗?为什么他们没有一个DataTable.sort("by")的函数呢? - Steam
33
谢谢。值得注意的是,“occr desc”中,“occr”是列名,“desc”表示“降序”。 - WSBT
26
这对我很有用 dataTable.DefaultView.Sort = "Col1, Col2, Col3"。代码简洁。 - Sai
7
就像 @Sai 一样,您可以直接修改 DataTable.DefaultView.Sort。不需要“打破”视图并重新创建表格。 - Jonny
显示剩余3条评论

63

这将有助于您...

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

1
聪明人想法相似。在阅读了@JayR的解决方案后,我也准备发布同样的解决方案。 - Drew Chapin
因为我对Jay Riggs的解决方案中发生了什么感到困惑,所以需要针对Column_name进行解释。 - Thameem
很棒且易于实现的解决方案 :) - M. Fawad Surosh

33

使用起来很简单,只需使用 .Select 函数即可。

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

完成了......编程愉快


2
请注意,如果您像 OP 一样只对排序方面感兴趣,而不想过滤结果,则可以这样指定:Select("", "CompanyName ASC") - Tawab Wakil
1
这是一个非常棒的答案。允许使用动态生成的文本字符串进行过滤和排序!很高兴我找到了这个答案! - kenmtb

22

也许以下内容可以帮助您:

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

在这里,您也可以使用其他Lambda表达式查询。


14

或者,如果可以使用 DataGridView,您可以只需调用 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);
        }
    }
}

以下方法可达到你所需的结果:

Debugger view


@vidyasagar 没问题。并且,作为参考,如果一个答案是有价值的,你应该投票支持它(例如,我的)。如果一个答案是“唯一正确”的答案,你应该将其标记为答案(例如,Jay的)。 - Gustavo Mori

14

你试过在DataTable上使用 Select(filterExpression, sortOrder) 方法吗?可以看这里示例。请注意,如果你需要的是原地排序,该方法将无法实现,但它将返回一个已排序的行数组而不使用数据视图。


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

Vidya想按照occr的降序对他的表进行排序。上面的简单代码就是这样做的。它完全做到了Jay Riggs(被接受的答案)所展示的,只不过这是用一行代码完成的。 - ivg
3
建议是改进帖子;将有关代码的信息放入回复中,这样可以增加某人点赞或选择其作为答案的机会。请在以后这样做。 - ΩmegaMan

6

使用LINQ——C#之美

DataTable newDataTable = baseTable.AsEnumerable()
                   .OrderBy(r=> r.Field<int>("ColumnName"))
                   .CopyToDataTable();

添加上下文以便我们学习,并防止问题被投票降低或删除。EoR. - ZF007

5

有两种方式可以对数据进行排序

1) 仅对数据进行排序并填充到网格中:

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) 默认视图排序,类似于带有网格列标题的排序:

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

1
感谢您的回答。您提供的方法#1对我的情况有所帮助:我定义了一个非常特殊的IComparer,因此为了使用它,我做了如下操作:DataRow[] rows = dt.Rows.Cast<DataRow>().OrderBy(row => row.Field<string>("FIELD_NAME"), MyCustomComparer.Instance).ToArray(); - Aleksei

4

事实证明,有一种特殊情况可以实现这一点。诀窍在于,在构建DataTable时,将所有行收集到列表中,对它们进行排序,然后添加它们。这种情况刚刚出现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接