排序和更新数据表不会产生预期的结果

时间:2011-03-31 02:22:59

标签: c# .net sorting datatable

编辑:解决这个问题 - 显然无法正常工作,因为排序dataTable没有对基础数据进行排序 - 从表中创建了一个dataView,工作正常。

我有一个数据表,我正在排序,然后迭代以删除一列中的重复值,但输出不是预期的。

数据表结构:

infoRow["Title"]
infoRow["QuickLink"]
infoRow["Description"]
infoRow["Date"]
infoRow["MonthName"]

我正在这样排序,工作正常,并按照递增的月份顺序生成一个表:

dataTable = dataTable.DefaultView.ToTable(true);
dataTable.DefaultView.Sort = "Date asc";

排序之后,我使用下面的代码将每一行与前一行进行比较,如果MonthName值相同,则将其替换为空字符串:

string prevMonthName = "";
foreach (DataRow row in dtEvents.Rows)
{
    string strMonthName = row["MonthName"].ToString();
    if (strMonthName == prevMonthName)
    {
        row["MonthName"] = "";
        row.AcceptChanges();
    }
    prevMonthName = strMonthName;
}           

所以,我遇到的问题是,即使我在排序后运行MonthName循环,它似乎也是针对未排序的数据运行的。它就像DefaultView.Sort只影响渲染输出而不对表进行物理重新排序,因此代码的第二部分不会产生我需要的结果。我是应该使用DataView还是偏离轨道......

3 个答案:

答案 0 :(得分:2)

我实际上有一个类似的,但略有不同的问题,你的问题给了我一个想法。事实证明,您的代码非常接近您(和我)所需要的。您需要做的就是翻转这两行排序代码,如下所示:

dataTable.DefaultView.Sort = "Date ASC";
dataTable = dataTable.DefaultView.ToTable(true);

现在,第一行代码对DefaultView进行排序。这对于您的DataGridView或ComboBox或您正在使用的任何内容来说都足够了,因为它们使用了DefaultView。但是,DataTable本身仍未排序。因此,第二行将DataTable设置为与排序的DefaultView完全相同。

我刚注意到你在顶部的编辑说你已经解决了它。这种“解决方案”似乎更像是一种解决方法。看到你如何拥有正确的代码,但错误的顺序,我想你会对这个答案感兴趣。

答案 1 :(得分:0)

假设dtEvents引用与datatable相同的对象,您可以尝试这样做:

string prevMonthName = "";
foreach (DataRowView row in dtEvents.DefaultView)
{
    string strMonthName = row["MonthName"].ToString();
    if (strMonthName == prevMonthName)
    {
        row["MonthName"] = "";
        row.AcceptChanges();
    }
    prevMonthName = strMonthName;
} 

答案 2 :(得分:0)

为了好玩,我想出了如何使用Linq to SQL做到这一点(假设我有一个带有上述模式的sql表)。由于我花时间搞清楚,我想我也可以分享它。

// Order the table and add an index column
var ordered = MonthTests.OrderBy(mt => mt.Date)
                        .AsEnumerable()
                        .Select((mt, index) => new
                        {
                            OrderId = index,
                            Record = mt
                        });

// Select out what we want
var query = from item in ordered
            let prev = ordered.FirstOrDefault (q => q.OrderId == (item.OrderId-1))
            select new 
            { 
                Title = item.Record.Title,
                QuickLink = item.Record.QuickLink,
                Date = item.Record.Date,
                MonthName = (prev != null && prev.Record.MonthName == item.Record.MonthName) ? "" : item.Record.MonthName
            };

玩得开心。