在資料處理過程中,DataTable 常因合併、查詢或手動新增導致重複列。本文介紹兩種移除重複資料的實用技巧:LINQ 查詢與 DataView 內建去重功能,皆能以簡潔程式碼完成。
透過 AsEnumerable() 將 DataTable 轉為可查詢序列,依指定欄位(此處為 "ID")分組,取每組第一筆,再匯入新的 DataTable:
DataTable testTable = new DataTable();
testTable.Columns.Add("ID");
testTable.Columns.Add("ProductName");
testTable.Rows.Add("1", "1");
testTable.Rows.Add("1", "1");
testTable.Rows.Add("1", "1");
testTable.Rows.Add("2", "2");
testTable.Rows.Add("3", "3");
// 複製結構並清空資料
DataTable finalTable = testTable.Clone();
finalTable.Clear();
// LINQ 分組去重
var distinctRows = from row in testTable.AsEnumerable()
group row by row["ID"] into grp
select grp.FirstOrDefault();
foreach (DataRow row in distinctRows)
{
finalTable.ImportRow(row);
}
優點: 邏輯靈活,可依多欄位分組(如 group row by new { ID = row["ID"], Name = row["ProductName"] }),亦可自訂排序後取特定列。
DataView 提供 ToTable(bool distinct, string[] columnNames) 多載方法,第一個參數設為 true 即啟用去重,第二個參數指定比較依據的欄位:
// 直接在原 DataTable 上操作,或建立副本
testTable = testTable.DefaultView.ToTable(true, new string[] { "ID", "ProductName" });
注意: 此法會依指定欄位「完全相同」判定重複,若需忽略大小寫或修剪空白,需先清洗資料再呼叫。
| 方法 | 適用場景 | 效能備註 |
|---|---|---|
| LINQ 分組 | 需複雜去重邏輯、多欄位組合、自訂排序取值 | 中等,大量資料建議改用 PLINQ 或分批處理 |
| DataView.ToTable | 單純欄位值完全相同即視為重複 | 極佳,內部最佳化,程式碼最簡潔 |
若只需快速去除完全重複列,DataView.ToTable(true, ...) 是首選;若業務邏輯較複雜(如取最新修改時間的一筆),LINQ 分組提供更大彈性。實務上可根據資料量與需求靈活選擇。