C# DataTable合并值并删除源行

C# DataTable合并值并删除源行,c#,datatable,C#,Datatable,我已经创建了一个Datatable,并试图减少行数。我能够找到一种方法来检查表中是否存在testID并合并主机名,但我不确定如何删除源行 示例d原始: testID passFail description hostname 1ab pass .... alpha 1ab pass .... bravo 1ab fail .... charlie 1ac pass .... alpha

我已经创建了一个Datatable,并试图减少行数。我能够找到一种方法来检查表中是否存在testID并合并主机名,但我不确定如何删除源行

示例
d原始

testID passFail description hostname
1ab    pass     ....        alpha
1ab    pass     ....        bravo
1ab    fail     ....        charlie
1ac    pass     ....        alpha
当前结果示例:

testID passFail description hostname
1ab    pass     ....        alpha, bravo
1ab    pass     ....        bravo
1ab    fail     ....        charlie
1ac    pass     ....        alpha
我想得到的

testID passFail description hostname
1ab    pass     ....        alpha, bravo
1ab    fail     ....        charlie
1ac    pass     ....        alpha
这是我当前的函数,可以在必要时合并主机名和testid

DataTable dtReducedColumns = CombineHostnames(dtOrinal).Copy();

private static DataTable CombineHostnames(DataTable dt)
    {
        for (int i = 0; i < dtOrginal.Rows.Count; i++)
        {
            bool isDupe = false;
            string a, b, c, d, e, f, g, h, k, l;

            for (int j = 0; j < dt.Rows.Count; j++)
            {
                a = dtOrginal.Rows[i][0].ToString(); //testID
                b = dt.Rows[j][0].ToString();
                c = dtOrginal.Rows[i][1].ToString(); //passFail
                d = dt.Rows[j][1].ToString();
                g = dtOrginal.Rows[i][2].ToString(); //description
                h = dt.Rows[j][2].ToString();
                if (a == b && c == d && g == h)
                {
                    e = dt.Rows[j][10].ToString();
                    f = dtOrginal.Rows[i][10].ToString(); //hostname
                    k = dtOrginalRows[i][8].ToString(); //source
                    l = dt.Rows[j][8].ToString();
                    if (!e.Contains(f))
                        dt.Rows[j][10] = e + ", " + f; //combine hostnames
                    if (!k.Contains(l))
                        dt.Rows[j][8] = k + ", " + l; //combine sources
                    isDupe = true;
                    //tried adding dt.Rows[j].Delete() here
                    //tried adding dt.Rows[j-1].Delete() here get -1 error
                    break;
                } 
               //tried adding dt.Rows[j].Delete() here
               //tried adding dt.Rows[j-1].Delete() here get -1 error
            }
            //tried adding dt.Rows[j].Delete() here
            //tried adding dt.Rows[j-1].Delete() here get -1 error

            if (!isDupe)
            {
                dt.ImportRow(dtOrginal.Rows[i]);
            }
        }
        return dt;
    }

这是
Linq To DataTable
的一个很好的用例,尤其是
可枚举的.GroupBy
+
字符串.Join

private static DataTable CombineHostnames(DataTable dtOrginal)
{
    DataTable tblresult = dtOrginal.Clone(); // empty table, same columns
    var rowGroups = dtOrginal.AsEnumerable()
        .GroupBy(row => new
        {
            Id = row.Field<string>("testId"),
            passFail = row.Field<string>("passFail")
        });

    foreach (var group in rowGroups)
    {
        DataRow row = tblresult.Rows.Add(); // already added now
        row.SetField("testId", group.Key.Id);
        row.SetField("passFail", group.Key.passFail);
        row.SetField("description", group.First()["description"]);  // the first?
        string hostNames = String.Join(", ", group.Select(r => r.Field<string>("hostname")));
        row.SetField("hostname", hostNames);
    }
    return tblresult;
}
专用静态数据表组合主机名(数据表dtOrginal)
{
DataTable tblresult=dtOrginal.Clone();//空表,相同列
var rowGroups=dtoriginal.AsEnumerable()
.GroupBy(行=>新建)
{
Id=行字段(“testId”),
passFail=行字段(“passFail”)
});
foreach(行组中的var组)
{
DataRow row=tblresult.Rows.Add();//现在已经添加了
row.SetField(“testId”,group.Key.Id);
row.SetField(“passFail”,group.Key.passFail);
row.SetField(“description”,group.First()[“description”]);//第一个?
string hostNames=string.Join(“,”,group.Select(r=>r.Field(“主机名”));
row.SetField(“主机名”,主机名);
}
返回tblresult;
}

您可以使用我已经添加的
说明
的方法添加其他列,只需使用每组的第一列或另一个逻辑即可。

太好了,非常感谢!由于testID是字母数字的,所以做了一些小的编辑,我将其更改为一个字符串,并且在
设置字段(“description”…)
中删除了一个额外的空格。在加入字符串之前,是否有方法进行检查?换句话说,有些字段我希望具有相同的ID,但来自不同的源,我想合并这些源,但只有唯一的源?我尝试使用.Distinct(),但它给了我这个
System.Linq.Enumerable+d_u63
1[System.Char]`好几次也许你可以问另一个问题,其他人可以提供帮助。我现在在度假:)哦,我刚刚创建了一个单独的助手方法。
private static DataTable CombineHostnames(DataTable dtOrginal)
{
    DataTable tblresult = dtOrginal.Clone(); // empty table, same columns
    var rowGroups = dtOrginal.AsEnumerable()
        .GroupBy(row => new
        {
            Id = row.Field<string>("testId"),
            passFail = row.Field<string>("passFail")
        });

    foreach (var group in rowGroups)
    {
        DataRow row = tblresult.Rows.Add(); // already added now
        row.SetField("testId", group.Key.Id);
        row.SetField("passFail", group.Key.passFail);
        row.SetField("description", group.First()["description"]);  // the first?
        string hostNames = String.Join(", ", group.Select(r => r.Field<string>("hostname")));
        row.SetField("hostname", hostNames);
    }
    return tblresult;
}