從 Excel 匯入資料前,常需檢查兩類重複:
// 假設 dt 為已填充的 DataTable,需檢查 Col1+Col2+Col3 組合唯一
var view = dt.DefaultView;
view.RowFilter = "Col1 = '值1' AND Col2 = '值2' AND Col3 = '值3'";
// view.Count > 0 表示有重複
或動態建構:
string filter = $"Col1 = '{val1}' AND Col2 = '{val2}' AND Col3 = '{val3}'";
var dupRows = dt.Select(filter); // 回傳 DataRow[]
///
/// 掃描 DataTable 找出重複列索引(以第 1、4、8 欄組合鍵為例)
///
private string FindDuplicateRows(DataTable dt)
{
var clone = dt.Clone(); // 僅複製結構,不複製資料
foreach (DataRow row in dt.Rows) clone.ImportRow(row);
var msg = new System.Text.StringBuilder();
for (int i = clone.Rows.Count - 1; i >= 0; i--)
{
var key1 = clone.Rows[i][1]?.ToString().Trim();
var key2 = clone.Rows[i][4]?.ToString().Trim();
var key3 = clone.Rows[i][8]?.ToString().Trim();
clone.Rows[i].Delete();
clone.AcceptChanges();
for (int j = clone.Rows.Count - 1; j >= 0; j--)
{
if (key1 == clone.Rows[j][1]?.ToString().Trim() &&
key2 == clone.Rows[j][4]?.ToString().Trim() &&
key3 == clone.Rows[j][8]?.ToString().Trim())
{
msg.AppendLine($"第 {i + 1} 列重複");
break;
}
}
}
return msg.ToString();
}
注意: 必須用 dt.Clone() + ImportRow 建立獨立副本,不可直接 var clone = dt;(那只是參考指派)。
foreach (DataRow row in dt.Rows)
{
string sql = "SELECT COUNT(*) FROM TargetTable WHERE Key1=@k1 AND Key2=@k2 AND Key3=@k3";
// 參數化查詢...
if ((int)cmd.ExecuteScalar() > 0) 記錄重複;
}
缺點:2000 筆約需 7 分 40 秒(單筆 ~2.3 秒),網路延遲放大。
// 1. 撈取資料庫所有比對鍵值
var dbKeys = new HashSet();
using (var da = new SqlDataAdapter("SELECT Key1, Key2, Key3 FROM TargetTable", conn))
{
var ds = new DataSet();
da.Fill(ds);
foreach (DataRow r in ds.Tables[0].Rows)
dbKeys.Add($"{r[0]}|{r[1]}|{r[2]}"); // 組合鍵字串
}
// 2. 逐筆比對
foreach (DataRow row in dt.Rows)
{
string composite = $"{row[1]}|{row[4]}|{row[8]}";
if (dbKeys.Contains(composite)) 記錄重複;
}
優點:單次資料庫往返,記憶體中 HashSet O(1) 查找,2000 筆可在秒級完成。
| 方案 | 適用資料量 | 2000 筆估計耗時 | 複雜度 |
|---|---|---|---|
| 逐筆查 DB | < 100 | ~460 秒 | O(N) × DB Roundtrip |
| DataSet + HashSet | 任意 | < 5 秒 | O(N) + O(M) |
| DataTable.Select/RowFilter | 純內部比對 | 極快 | O(N²) 最差,但 N 小時可接受 |
原文連結:https://www.bianceng.cn/Programming/csharp/201410/45747.htm