【问题标题】:DataTable sorting does not sort properly after mergingDataTable排序合并后排序不正确
【发布时间】:2019-01-08 03:15:27
【问题描述】:

我有 2 个使用 .Merge 方法组合的数据表。

2 个数据表的列类型为System.Decimal。 但它似乎没有正确排序。第一个数据表的数据将首先排序,然后是第二个数据表的数据。

所以如果你看到上图,它会显示第一个DataTable数据,然后是第二个DataTable,按开始时间排序。

如果我反转排序,它将按降序对第 2 个 DataTable 数据进行排序,然后会出现第 1 个 DataTable。

这是我的排序代码

DataView dv = new DataView(dataTableResult);
dv.Sort = string.Format("{0} {1}", ViewState["sortexp"].ToString(), 
GetSortDirection());
return dv;

ViewState["sortexp"] 在这种情况下包含开始时间,GetSortDirection 是“ASC”或“DESC”。

我的查询:

select  ....
        to_number(to_char([start_field],'hh24mi')) as start_time, 
        to_number(to_char([end_field], 'hh24mi')) as end_time,
        ...
from    [table]
where   [condition]

另一个我从 web 服务获取结果并手动填充数据行。

foreach (DTResult dtr in result)
{
    DataRow dr = dtTable2.NewRow();
    ...
    dr["start_time"] = Decimal.Parse(dtr.start_time.Replace(":", ""));
    dr["end_time"] = Decimal.Parse(dtr.end_time.Replace(":", ""));
    ...
    dtTable2.Rows.Add(dr);
}       

以及合并代码

dataTableResult.Merge(dtTable1);
dataTableResult.Merge(dtTable2);

dtTable 列的定义:

...
dtTable2.Columns.Add("start_time", typeof(decimal));
dtTable2.Columns.Add("end_time", typeof(decimal));
...

如何解决这个问题?

【问题讨论】:

  • 你可能认为所有的Fields类型都是decimal。这些表的Start Time 字段(或所有字段)有可能是string 类型。
  • 我已经把它转换成十进制了。
  • 是的,好吧,dtTable 是什么?它的字段 object 类型?这个排序结果很可能来自字符串评估。检查两次,同时调试。
  • 我会更新 dtTable 的定义,请看一下。
  • 好的。您是否真的在调试模式下检查了合并的表格内容=> dataTableResult -> Rows -> Result View -> [0] -> ItemArray,以便在设置某些东西的 DataSource 之前查看行的实际内容?如果这些值不都是相同的类型,您应该在那里看到它。如果它们都是相同的对象数据类型(十进制,这里),我不知道为什么它们不应该正确排序。

标签: c# sorting datatable


【解决方案1】:

调试后发现是由于dataTableResult.Merge(dtTable2);命令在dataTableResult新建列,导致列数翻倍。

所以dataTableResult 的内容类似于以下内容:

--------------------------------------------------------------------
|Rows              | start_time | end_time | start_time | end_time |
--------------------------------------------------------------------
|0                 | 1200       | 1400     | NULL       | NULL     | --> 1st data table merge
|1                 | 800        | 1000     | 800        | 1000     | --> 2nd data table merge
|2                 | 1400       | 1600     | 1400       | 1600     | --> 2nd data table merge
|3                 | 1600       | 1800     | 1600       | 1800     | --> 2nd data table merge
--------------------------------------------------------------------

列名只是为了说明,因为我看不到实际的列名。因此,一旦合并了第二个数据表,它就会创建新列。第一个数据表的新列包含 NULL。并且第二个数据表的列内容将被重复(就像两个 start_time 列将具有相同的值)。 不过这很奇怪。

所以这是我解决问题的方法:

dataTableResult中,我将定义所有使用大写字母作为列名的列。由于某种原因,前面的查询使用的是普通字母,这​​导致它加倍。

dataTableResult.Columns.Add("START_TIME", typeof(decimal));
dataTableResult.Columns.Add("END_TIME", typeof(decimal));

那么在Database Query中,我也会用大写字母作为列名别名

select  ....
        to_number(to_char([start_field],'hh24mi')) as START_TIME, 
        to_number(to_char([end_field], 'hh24mi')) as END_TIME,
        ...
from    [table]
where   [condition]    

对于第二个数据表也是如此

dtTable2.Columns.Add("START_TIME", typeof(decimal));
dtTable2.Columns.Add("END_TIME", typeof(decimal));

这样,在调用dataTableResult.Merge(dtTable2);时,生成的数据表不会有重复的列,并且排序问题得到修复。

【讨论】:

    猜你喜欢
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多