如何迭代DataTable并根据列值获取行组

本文关键字:获取 何迭代 迭代 DataTable | 更新日期: 2023-09-27 18:28:45

我有一个DataTable,基本上看起来像这样:

Id   |    parentId
__________________
1    |    100
2    |    100
3    |    200
4    |    300
5    |    300
6    |    300
7    |    400
8    |    400

正如您所看到的,每一行都有一个唯一的ID,并由父行的ID(Int64)分配给父行。此外,每个父级可以包含多行
在我的情况下,父项是我们系统中的票证,行是该票证的附件。

我想迭代DataTable,这样我就可以处理附件,但我需要根据parentId的值分组处理。这是因为,如果只有一个附件无法处理,那么整个组就会失败,必须回滚,然后我将继续处理其他票证。

我可以通过类似于以下(伪代码)的if语句来实现这一点:

var currentParent = 0;
foreach (var row in table.Rows)
{
    if (row["parentId"] == currentParent)
    {
        // Same group
    }
    else
    {
        // New group
    }
    currentParent = row["parentId"];
}

这是有效的,但我觉得很混乱,因为如果100个项目中的第一个项目失败了,它仍然需要检查剩下的99个项目。

我一直在尝试使用LINQIEnumerable来获取每组行,并可能将它们放入自己的临时DataTable中的解决方案。如果遇到错误,这将使迭代和跳过变得容易。不幸的是,我甚至不确定我在寻找什么功能,所以我被卡住了。

我认为GroupBy听起来不错,并尝试了这个:

var results = table.AsEnumerable().GroupBy(row => row.Field<Int64>("parentId"));

不幸的是,这只返回4行,这是有道理的,因为在我的示例中只有4个不同的父级。

我在寻找更像这样的东西:

var count = temporaryDataTable.Rows.Count();
// After first "grab" of a group 'count' is 2 for parentId 100  
// temporaryDataTable contains Id values 1 & 2.
// After second "grab" 'count' is 1 for parentId 200  
// temporaryDataTable contains Id value 3.
// After third "grab" 'count' is 3 for parentId 300  
// temporaryDataTable contains Id values 4, 5 & 6.
// Last "grab" 'count' is 2 for parentId 400  
// temporaryDataTable contains Id values 7 & 8.

或者,我可能在这里偏离了目标,所以如果有比LINQ更适合以这种方式获取数据的东西,请告诉我。谢谢!

如何迭代DataTable并根据列值获取行组

一旦对results进行分组,就可以使用此循环迭代您的组:

foreach (var group in results)
{
    // This will get the parentId value in the group.
    var parentId = group.Key;
    // This will get all the Ids contained in the group.
    foreach (var Id in group)
    {
        // Do something with Id. If something goees wrong
        // and you want to proceed with the next group,
        // just put a break; inside this foreach.
    }
}