DataTable组合值并删除源行
本文关键字:删除 组合 DataTable | 更新日期: 2023-09-27 18:01:12
我已经创建了一个Datatable,我正在努力减少行数。我找到了一种方法来检查表中是否存在testID并合并主机名,但我不知道如何删除源行。
示例dtOrginal
:
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
这是我目前的功能,在必要时合并主机名和测试ID
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;
}
我尝试删除行的地方要么抛出IndexOutOfBounds
异常,要么返回类似于dtOrginal
的表。
作为参考,以下是我正在使用的整个DataTable:
dtChecklistFindingsTable = new DataTable(); //Column Number
dtChecklistFindingsTable.Columns.Add("testID", typeof(string)); // 0
dtChecklistFindingsTable.Columns.Add("passFail", typeof(string)); // 1
dtChecklistFindingsTable.Columns.Add("description", typeof(string)); // 2
dtChecklistFindingsTable.Columns.Add("vulLevel", typeof(string)); // 3
dtChecklistFindingsTable.Columns.Add("recommendation", typeof(string)); // 4
dtChecklistFindingsTable.Columns.Add("comments", typeof(string)); // 5
dtChecklistFindingsTable.Columns.Add("title", typeof(string)); // 6
dtChecklistFindingsTable.Columns.Add("testCheck", typeof(string)); // 7
dtChecklistFindingsTable.Columns.Add("source", typeof(string)); // 8
dtChecklistFindingsTable.Columns.Add("date", typeof(string)); // 9
dtChecklistFindingsTable.Columns.Add("hostName", typeof(string)); // 10
dtChecklistFindingsTable.Columns.Add("os", typeof(string)); // 11
dtChecklistFindingsTable.Columns.Add("ipAddr", typeof(string)); // 12
dtChecklistFindingsTable.Columns.Add("stigLevel", typeof(string)); // 13
dtChecklistFindingsTable.Columns.Add("stigSeverity", typeof(string)); // 14
dtChecklistFindingsTable.Columns.Add("sarStatus", typeof(string)); // 15
dtChecklistFindingsTable.Columns.Add("iaControl", typeof(string)); // 16
这是Linq-To-DataTable
的一个很好的用例,尤其是Enumerable.GroupBy
+String.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;
}
您可以像我已经添加description
一样添加其他列,只需使用每组中的第一个或通过另一个逻辑即可。