You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中按两列对矩阵(DataTable)进行分组?

在C#中对DataTable按多列分组的实现方法

针对你需要将DataTable中column1和column2值均相同的行归为一组的需求,以下是两种常用的实现方式:

方法一:使用LINQ to DataSet(推荐)

这种方式代码简洁、可读性高,是处理DataTable分组的首选方案。需要确保项目引用了System.Data.DataSetExtensions程序集,并引入System.Linq命名空间。

代码示例

using System;
using System.Data;
using System.Linq;

class Program
{
    static void Main()
    {
        // 示例DataTable(假设已初始化并填充数据)
        DataTable dt = new DataTable();
        dt.Columns.Add("column1", typeof(string));
        dt.Columns.Add("column2", typeof(int));
        dt.Columns.Add("column3", typeof(decimal));
        
        dt.Rows.Add("A", 1, 100.5m);
        dt.Rows.Add("A", 1, 200.3m);
        dt.Rows.Add("B", 2, 150.7m);
        dt.Rows.Add("A", 2, 300.2m);
        dt.Rows.Add("B", 2, 400.9m);

        // 按column1和column2分组,处理DBNull避免异常
        var groups = dt.AsEnumerable()
                       .GroupBy(row => new 
                       {
                           Column1 = row.IsNull("column1") ? null : row["column1"],
                           Column2 = row.IsNull("column2") ? null : row["column2"]
                       });

        // 遍历分组并输出结果
        foreach (var group in groups)
        {
            Console.WriteLine($"分组键:column1={group.Key.Column1}, column2={group.Key.Column2}");
            foreach (DataRow row in group)
            {
                Console.WriteLine($"  column3值:{row["column3"]}");
            }
        }
    }
}

说明

  • dt.AsEnumerable()将DataTable转换为支持LINQ操作的DataRow集合
  • 匿名类型作为分组键,同时处理列值为DBNull的情况,避免分组逻辑异常
  • group.Key可获取当前组的column1和column2值,group本身是该组所有DataRow的集合

方法二:手动使用字典分组

如果项目无法使用LINQ,可通过字典手动实现分组逻辑,将(column1, column2)的组合作为字典的键,对应的值为该组的DataRow列表。

代码示例

using System;
using System.Data;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 示例DataTable
        DataTable dt = new DataTable();
        dt.Columns.Add("column1", typeof(string));
        dt.Columns.Add("column2", typeof(int));
        dt.Columns.Add("column3", typeof(decimal));
        
        dt.Rows.Add("A", 1, 100.5m);
        dt.Rows.Add("A", 1, 200.3m);
        dt.Rows.Add("B", 2, 150.7m);
        dt.Rows.Add("A", 2, 300.2m);
        dt.Rows.Add("B", 2, 400.9m);

        // 字典存储分组,键为column1和column2的组合
        Dictionary<Tuple<object, object>, List<DataRow>> groupsDict = new Dictionary<Tuple<object, object>, List<DataRow>>();

        foreach (DataRow row in dt.Rows)
        {
            // 获取列值并处理DBNull
            object val1 = row.IsNull("column1") ? DBNull.Value : row["column1"];
            object val2 = row.IsNull("column2") ? DBNull.Value : row["column2"];
            var key = Tuple.Create(val1, val2);

            if (!groupsDict.ContainsKey(key))
            {
                groupsDict[key] = new List<DataRow>();
            }
            groupsDict[key].Add(row);
        }

        // 遍历字典输出分组结果
        foreach (var kvp in groupsDict)
        {
            Console.WriteLine($"分组键:column1={kvp.Key.Item1}, column2={kvp.Key.Item2}");
            foreach (DataRow row in kvp.Value)
            {
                Console.WriteLine($"  column3值:{row["column3"]}");
            }
        }
    }
}

说明

  • Tuple<object, object>作为字典键,确保column1和column2的组合唯一
  • 手动遍历每一行,判断键是否存在,不存在则创建新列表,存在则添加当前行
  • 同样处理了DBNull的情况,保证分组逻辑的准确性

注意事项

  1. 数据类型匹配:确保分组时column1和column2的值类型一致,避免因类型差异导致分组错误(如字符串"1"和整数1会被视为不同键)
  2. 空值处理:若列可能存在DBNull值,必须提前处理,否则会引发异常或分组不准确
  3. 性能考虑:超大DataTable场景下,两种方式性能差异不大,可根据项目环境选择

内容的提问来源于stack exchange,提问作者Balázs Kis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 15:36:27