[英]Sort a DataTable in .NET with thousands of records using C# .Net
我正在运行一个非常密集的数据查询(因此超时很长)但想知道如何正确排序DataTable
。
我的代码是这样开始的:
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand command = new SqlCommand(sql, conn);
command.CommandTimeout = 36000;
da.SelectCommand = command;
DataTable dt = new DataTable();
da.Fill(dt);
DataView dv = new DataView(dt);
// Sorting
dv.Sort = "theId DESC";
int i = 0;
while (dt.Rows.Count > 0 && i < 5)
{
DataRow row = dt.Rows[i];
string theId = row["theId"].ToString();
i++;
}
theId
有大约 2,000 条记录,这些记录按数字顺序从 1 到 2,000。
警告或不在 SQL 中使用ORDER BY
是由于异常:
错误:发生异常
查询处理器无法生成查询计划,因为需要一个工作表,并且它的最小行大小超过了 8060 字节等的最大允许值。
由于最大列大小为 1,024,我也无法即时创建#TempTable
。
以某种方式编写查询的原因是由于系统和网络的限制,我无法调整,也无法在本地运行查询。
我如何让排序后的DataTable
工作,因为这是需要传递到下一个 function 的内容,这也是我无法控制的,因为它是对另一个系统的 api 调用?
您无法真正对DataTable
进行排序。 正如您所做的那样,您可以通过DataView
进行操作,但这只会对视图进行排序,而不会对表格进行排序。 如果您随后通过Rows
集合访问数据,您将看不到排序。 您必须通过DataView
访问数据。
但是实际上不需要显式创建DataView
。 每个DataTable
在其DefaultView
属性中已经有一个DataView
。 当您在 WinForms 中绑定DataTable
时,这就是 dusplayed 数据的来源。 这就是您可以在DataGridView
中或通过BindingSource
对数据进行排序的方式。
当您使用Rows
集合时,您将获得DataRow
对象。 当您使用DefaultView
时,您将获得DataRowView
对象。 它们在许多方面非常相似,但也有一些差异。 如果您只需要数据,您可以使用列名进行索引并获取值,因此它们在这方面的工作方式相同。 如果您通过DefaultView
访问数据但出于某种原因需要DataRow
,则可以通过DataRowView
的Row
属性访问它。 试试这段代码看看它是如何工作的:
var table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Rows.Add("Peter");
table.Rows.Add("Paul");
table.Rows.Add("Mary");
Console.WriteLine("Rows, unsorted");
foreach (DataRow row in table.Rows)
{
Console.WriteLine(row["Name"]);
}
Console.WriteLine("DefaultView, unsorted");
foreach (DataRowView rowView in table.DefaultView)
{
Console.WriteLine(rowView["Name"]);
}
table.DefaultView.Sort = "Name";
Console.WriteLine("Rows, sorted");
foreach (DataRow row in table.Rows)
{
Console.WriteLine(row["Name"]);
}
Console.WriteLine("DefaultView, sorted");
foreach (DataRowView rowView in table.DefaultView)
{
Console.WriteLine(rowView["Name"]);
}
Console.WriteLine("DefaultView to DataRow, sorted");
foreach (DataRowView rowView in table.DefaultView)
{
Console.WriteLine(rowView.Row.Field<string>("Name"));
}
从中可以看出, Rows
集合中的数据在排序前后是相同的,而DefaultView
按指定顺序显示数据。 最后一个循环显示了如何从DataRowViews
访问DataRows
,然后在DataRowViews
不能访问的地方使用它们,例如在 LINQ 中使用 DataSet 方法。
请注意,如果您确实需要对DataTable
本身进行排序,那么您可以在DataView
上调用ToTable
以生成一个新的DataTable
。 新表将包含基于DataView
的Sort
和RowFilter
属性的数据,如果需要,您也可以省略一些列。 您还可以指定只包含不同的记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.