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

时间:2015-12-31 11:47:25

标签: c# linq datatable

我的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的东西以这种方式获取数据,那么请告诉我。谢谢!

1 个答案:

答案 0 :(得分:1)

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.
    }
}