C# DataTable合并值并删除源行
我已经创建了一个Datatable,并试图减少行数。我能够找到一种方法来检查表中是否存在testID并合并主机名,但我不确定如何删除源行 示例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
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;
}