使用c# . net对.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的警告是由于异常:

ERROR: Exception occurred
查询处理器无法生成查询计划,因为需要一个工作表,并且它的最小行大小超过了允许的最大8060字节,等等

我也不能即时创建#TempTable,因为最大列大小为1,024。

以某种方式编写查询的原因是由于我给出的系统和网络的限制,不能调整,也不能在本地运行。

我如何得到排序的DataTable工作,因为这是需要传递到下一个函数,这也是我的控制之外,因为它是一个api调用到另一个系统?

你不能真正排序一个DataTable。您可以通过DataView进行排序,正如您所做的那样,但这只对视图排序,而不是对表排序。如果随后通过Rows集合访问数据,则不会看到排序。你必须通过DataView访问数据。

实际上不需要显式地创建DataView。每个DataTable在其DefaultView属性中已经有一个DataView。当您在WinForms中绑定DataTable时,这就是未播放数据的来源。这就是如何在DataGridView中或通过BindingSource对数据进行排序。

当您使用Rows集合时,您将获得DataRow对象。当您使用DefaultView时,您将获得DataRowView对象。他们在许多方面很相似,但也有一些不同之处。如果您只需要数据,则可以使用列名进行索引并获取值,因此它们在这方面的工作方式相同。如果您通过DefaultView访问数据,但由于某种原因需要DataRow,则可以通过DataRowViewRow属性访问它。试试下面的代码,看看它是如何工作的:

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 to DataSet方法中。

注意,如果你真的需要对DataTable本身进行排序,那么你可以在DataView上调用ToTable来生成一个新的DataTable。新表将包含基于DataViewSortRowFilter属性的数据,如果您愿意,也可以省略一些列。您还可以指定只包含不同的记录。

最新更新