如何使用IComparable之类的东西自然地对DataView进行排序

时间:2008-09-18 04:22:48

标签: .net asp.net dataview icomparable

我的DataView表现得很有趣,它按字母顺序排序,我需要用数字排序。我已经浏览了整个网络,并发现了很多关于如何使用ICompare对其进行排序的想法,但没有什么真正可靠的。

所以我的问题是

  1. 如何在DataView上实现ICompare(在此处查找代码)。
  2. 如何从充满字符串的列中正确解密,这些字符串是实际字符串和一个满数字的列(带逗号)。
  3. 我需要代码来帮助我解决这个问题。我或多或少迷失在ICompare的想法以及如何在不同的场景中实现,所以一个好的解释会很棒。

    另外,请不要给我链接。我正在寻找这个问题的可靠答案。

    我使用的一些代码。

        DataView dataView = (DataView)Session["kingdomData"];
        dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
        gvAllData.DataSource = dataView;
        gvAllData.DataBind();
    
    
    
        private string ConvertSortDirectionToSql(SortDirection sortDirection)
    {
        string newSortDirection = String.Empty;
        if (Session["SortDirection"] == null)
        {
            switch (sortDirection)
            {
                case SortDirection.Ascending:
                    newSortDirection = "ASC";
                    break;
                case SortDirection.Descending:
                    newSortDirection = "DESC";
                    break;
            }
        }
        else
        {
            newSortDirection = Session["SortDirection"].ToString();
            switch (newSortDirection)
            {
                case "ASC":
                    newSortDirection = "DESC";
                    break;
                case "DESC":
                    newSortDirection = "ASC";
                    break;
            }
        }
        Session["SortDirection"] = newSortDirection;
        return newSortDirection;
    }
    

3 个答案:

答案 0 :(得分:3)

对于第一个问题 - IIRC,您无法使用比较器对DataView进行排序。如果只需要在数字上对字段进行排序,则必须确保列类型为数字而不是字符串。一些代码有助于阐明这一点。

对于第二个问题,您也无法直接在DataView中执行此操作。如果你真的需要根据列中的一些数据处理对记录进行排序,那么我将数据复制到一个数组中并在数组上使用IComparer:

DataView dv = new DataView(dt);
ArrayList lst = new ArrayList();
lst.AddRange(dv.Table.Rows);
lst.Sort(new MyComparer());
foreach (DataRow dr in lst)
    Debug.WriteLine(dr[0]);

比较器是这样的:

    class MyComparer : IComparer
    {
        public int Compare(object x, object y)
        {
            DataRow rx = x as DataRow;
            DataRow ry = y as DataRow;
            string datax = (string)rx[colName];
            string datay = (string)ry[colName];
            // Process datax and datay here then compare them (ASC)
            return datax.CompareTo(datay);
        }
    }

这会增加内存消耗,因此您需要考虑是否有更好的方法来预处理表中的数据,以便您可以按列直接对DataView进行排序。

P.S。 colName是您要排序的列的名称。用实际代码替换注释以从列中提取排序信息。您还可以使用此方法从更多列中提取排序信息。只需使用这样的东西:

int cmp = colAx.CompareTo(colAy);
if (cmp != 0)
    return cmp;
cmp = colBy.CompareTo(colBx);
return cmp;

这将比较colA值的升序,然后按colB值降序(不是第二个比较首先 y 然后 x

编辑:好的,我错误地解释了术语逗号分隔值。从你的例子中我认为你实际上意味着数千个分隔符(1,000,000 =一百万)。如果您在数据库中存储这样的数字,那么您必须使用文本字段,这应该是您的排序顺序是字母数字的原因。

基于这个假设,我建议将该列的类型更改为数字,保留正常数字并将其格式化(使用千位分隔符)仅在显示时。这样排序应该直接在DataView中工作,您不必复制数据。

答案 1 :(得分:1)

这很难看,但是:

        DataView dv = GetDataViewSomewhere();

        //Naturally sort by COLUMN_TO_SORT_ON
        try
        {
            List<string> rowList = new List<string>();
            foreach (DataRowView drv in dv)
                rowList.Add((string)drv["COLUMN_TO_SORT_ON"]);
            rowList.Sort(new NaturalComparer());
            Dictionary<string, int> sortValueHash = new Dictionary<string, int>();
            for (int i = 0; i < rowList.Count; i++)
                sortValueHash.Add(rowList[i], i);                                    

            dv.Table.Columns.Add("NATURAL_SORT_ORDER", typeof(int));
            foreach (DataRowView drv in dv)
                drv["NATURAL_SORT_ORDER"] = sortValueHash[(string)drv["COLUMN_TO_SORT_ON"]];
            dv.Sort = "NATURAL_SORT_ORDER";                
        }
        catch (Exception)
        {                
            DEBUG_TRACE("Could not naturally sort");
            dv.Sort = "COLUMN_TO_SORT_ON";
        }

NaturalComparerthis class

答案 2 :(得分:0)

对于场景,我动态构建数据表并将其推送到数据视图中,我将数据视图放入gridview,同时还记住将数据视图放入会话对象以进行排序功能。

当用户调用gridview对列进行排序时,我会在会话对象中调用dataview并构建数据视图排序表达式,如下所示:

dataview.sort = e.sortexpression + " " + e.Sortdirection; 

或者那些东西。因此,对于所有真正的字符串,例如

,通常出现的是正确的

汽车;家;斯科特;扎克等...

但是当我对数字字段使用逗号分隔值执行相同操作时,它会出现类似

的内容

900; 800; 700; 600; 200; 120; 1200; 12340;百万;

明白我的意思?它只是将项目排序为alpha排序而不是自然排序。我想让我的Dataview自然地对数字列进行正确排序,如

120; 200; 600; 700; 800; 900; 1200; 12340;百万;

让我知道你可以做些什么来帮助我 附:我已经浏览了无数关于如何做到这一点的文章,所有人都说要推入List / Array并按照这种方式进行,但是有更有效的方法吗?