none
请问如何对一个DataSet中的DataTable按某些列进行分组? 目前.net是否自带有这种功能? RRS feed

  • 问题

  • 具体情况如下:

       比如说现在有数据集Ds, 如何对Ds.Tables[0]按照某几列进行分组? 具体做为分组依据的列并不固定,有可能一列,有可能几列,能否做一个通用的分组实现?

       比如实现一个方法:

        public List<DataTable> GetDataTableGroupList(DataTable dt, List<string> fieldNameList)

       {

                 Do。。。。。。。。。。

       }

      然后如下调用:

    List<string> fieldNameList = new List<string>();  

    fieldNameList.add("列a");

    fieldNameList.add("列b");

    List<DataTable> dtList = GetDataTableGroupList(Ds.Tables[0],  fieldNameList);

    传入需要进行分组的数据集和作为分组依据的列

    返回的结果是得到的分组的一个列表,每个组放在一个DataTable里面。

    .net目前自带有这样的功能么?

    2010年7月15日 5:48

答案

  •     public static void GroupDataRows(IEnumerable<DataRow> source,List<DataTable> destination, string[] groupByFields, int fieldIndex, DataTable schema)
        {
          if (fieldIndex >= groupByFields.Length || fieldIndex < 0 )
          {
            DataTable dt = schema.Clone();
            foreach (DataRow row in source)
            {
              DataRow dr = dt.NewRow();
              dr.ItemArray = row.ItemArray;
              dt.Rows.Add(dr);
            }
    
            destination.Add(dt);        
            return;
          }
    
          var results = source.GroupBy(o => o[groupByFields[fieldIndex]]);
          foreach (var rows in results)
          {
            GroupDataRows(rows, destination, groupByFields, fieldIndex + 1, schema);
          }
    
          fieldIndex++;
        }
    

    调用方法:

        private void button3_Click(object sender, EventArgs e)
        {
          DataTable source = new DataTable();
          source.Columns.Add(new DataColumn("A",typeof(int)));
          source.Columns.Add(new DataColumn("B", typeof(int)));
          source.Columns.Add(new DataColumn("C", typeof(int)));
          source.Columns.Add(new DataColumn("D", typeof(int)));
    
          DataRow dr = source.NewRow();      
          dr[0] = 2;
          dr[1] = 4;
          dr[2] = 5;
          dr[3] = 7;
          source.Rows.Add(dr);
    
          dr = source.NewRow();
          dr[0] = 1;
          dr[1] = 10;
          dr[2] = 8;
          dr[3] = 6;
          source.Rows.Add(dr);
    
          dr = source.NewRow();
          dr[0] = 1;
          dr[1] = 11;
          dr[2] = 8;
          dr[3] = 9;
          source.Rows.Add(dr);      
    
          dr = source.NewRow();
          dr[0] = 2;
          dr[1] = 3;
          dr[2] = 20;
          dr[3] = 1;
          source.Rows.Add(dr);
    
          string[] fileds = new string[] { "A","C"}; // 分组条件
          List<DataTable> grouped = new List<DataTable>(); // 存储分组结果
    
          GroupDataRows(source.Rows.Cast<DataRow>(), grouped, fileds, 0, source);   
     
          // 输出分组
          foreach (DataTable dt in grouped)
          {
            Console.WriteLine(string.Format("分组:{0},记录数:{1}",dt.TableName,dt.Rows.Count));
            foreach (DataRow row in dt.Rows)
            {
              foreach (object value in row.ItemArray)
              {
                Console.Write(value+"       ");
              }
    
              Console.WriteLine();
            }
          }
        }
    
    • 已标记为答案 Alex-Frog 2010年7月19日 2:29
    2010年7月16日 10:09

全部回复

  • 具体情况如下:

       比如说现在有数据集Ds, 如何对Ds.Tables[0]按照某几列进行分组? 具体做为分组依据的列并不固定,有可能一列,有可能几列,能否做一个通用的分组实现?

       比如实现一个方法:

        public List<DataTable> GetDataTableGroupList(DataTable dt, List<string> fieldNameList)

       {

                 Do。。。。。。。。。。

       }

      然后如下调用:

    List<string> fieldNameList = new List<string>();  

    fieldNameList.add("列a");

    fieldNameList.add("列b");

    List<DataTable> dtList = GetDataTableGroupList(Ds.Tables[0],  fieldNameList);

    传入需要进行分组的数据集和作为分组依据的列

    返回的结果是得到的分组的一个列表,每个组放在一个DataTable里面。

    .net目前自带有这样的功能么?

    2010年7月15日 5:42
  • 没有人知道么。。。
    2010年7月15日 6:33
  • 你是要根据列名分组,还是根据某列的字段的值分组?
    2010年7月15日 10:00
  •       DataTable dt = new DataTable();
          dt.Columns.Add(new DataColumn("C1", typeof(int)));
          dt.Columns.Add(new DataColumn("C2", typeof(string)));
          dt.Columns.Add(new DataColumn("C3", typeof(int)));
          dt.Rows.Add(1, "a", 30);
          dt.Rows.Add(2, "a", 40);
          dt.Rows.Add(3, "b", 50);
          dt.Rows.Add(4, "b", 60);
          dt.Rows.Add(5, "c", 70);
          dt.Rows.Add(6, "c", 80);
          dt.Rows.Add(7, "d", 90);
          List<string> list = new List<string>();
          foreach (DataRow dr in dt.Rows)
          {
            if (!list.Contains(dr["C2"].ToString()))
            {
              Console.WriteLine(dr["C2"] + "总和:" + dt.Compute("sum(C3)", "C2='" + dr["C2"] + "'"));
              list.Add(dr["C2"].ToString());
            }
          }
    

    http://blog.csdn.net/zx13525079024
    2010年7月15日 10:11
  • 就是根据某些列的字段的值分组, 跟SQL里面Group By一样的, 不需要做汇总什么的,只要需要简单的得到: 某个DataTable根据某些列分组以后,得到的结果。

    比如:

    A      B       C       D

    1      10      8      6

    1      11      8       9

    2      4        5       7

    2      3       20      1

    如果根据A列分组,结果会得到2个组,这2个组放到2个DataTable中。

    第一组是:

    1      10      8       6

    1      11      8       9

    第二组是:

    2      4        5       7

    2      3       20      1

     

    如果根据A, C两列分组,结果会得到3个组,这3个组放到3个DataTable中。

    第一组是:

    1      10      8      6

    1      11      8       9

    第二组是:

    2      4        5       7

    第三组是:

    2      3       20      1

     

     

    2010年7月15日 10:20
  •     public static void GroupDataRows(IEnumerable<DataRow> source,List<DataTable> destination, string[] groupByFields, int fieldIndex, DataTable schema)
        {
          if (fieldIndex >= groupByFields.Length || fieldIndex < 0 )
          {
            DataTable dt = schema.Clone();
            foreach (DataRow row in source)
            {
              DataRow dr = dt.NewRow();
              dr.ItemArray = row.ItemArray;
              dt.Rows.Add(dr);
            }
    
            destination.Add(dt);        
            return;
          }
    
          var results = source.GroupBy(o => o[groupByFields[fieldIndex]]);
          foreach (var rows in results)
          {
            GroupDataRows(rows, destination, groupByFields, fieldIndex + 1, schema);
          }
    
          fieldIndex++;
        }
    

    调用方法:

        private void button3_Click(object sender, EventArgs e)
        {
          DataTable source = new DataTable();
          source.Columns.Add(new DataColumn("A",typeof(int)));
          source.Columns.Add(new DataColumn("B", typeof(int)));
          source.Columns.Add(new DataColumn("C", typeof(int)));
          source.Columns.Add(new DataColumn("D", typeof(int)));
    
          DataRow dr = source.NewRow();      
          dr[0] = 2;
          dr[1] = 4;
          dr[2] = 5;
          dr[3] = 7;
          source.Rows.Add(dr);
    
          dr = source.NewRow();
          dr[0] = 1;
          dr[1] = 10;
          dr[2] = 8;
          dr[3] = 6;
          source.Rows.Add(dr);
    
          dr = source.NewRow();
          dr[0] = 1;
          dr[1] = 11;
          dr[2] = 8;
          dr[3] = 9;
          source.Rows.Add(dr);      
    
          dr = source.NewRow();
          dr[0] = 2;
          dr[1] = 3;
          dr[2] = 20;
          dr[3] = 1;
          source.Rows.Add(dr);
    
          string[] fileds = new string[] { "A","C"}; // 分组条件
          List<DataTable> grouped = new List<DataTable>(); // 存储分组结果
    
          GroupDataRows(source.Rows.Cast<DataRow>(), grouped, fileds, 0, source);   
     
          // 输出分组
          foreach (DataTable dt in grouped)
          {
            Console.WriteLine(string.Format("分组:{0},记录数:{1}",dt.TableName,dt.Rows.Count));
            foreach (DataRow row in dt.Rows)
            {
              foreach (object value in row.ItemArray)
              {
                Console.Write(value+"       ");
              }
    
              Console.WriteLine();
            }
          }
        }
    
    • 已标记为答案 Alex-Frog 2010年7月19日 2:29
    2010年7月16日 10:09
  • 这个应该是用了Linq的功能了吧,这种是可以的,不过我现在的开发考虑到客户需要安装framework的缘故,还是用的framework 2.0=。=, 不过已经解决了,自己写了一段Group的代码,凑合能用了=。=

     

    谢谢

    2010年7月19日 2:32
  • 不知道你還上不上,你最後怎麼弄的?例子還在嗎?
    2010年11月12日 4:10