網路廣泛流傳的 DataTable 比較演算法存在嚴重缺陷:僅比較行數、列數與首行資料,若第一行相同、第二行不同,仍回傳 true。本文揭露錯誤並提供正確實作。
private bool ValueEquals(DataTable objA, DataTable objB) {
if (objA != null && objB != null) {
if (objA.Rows.Count != objB.Rows.Count) return false;
if (objA.Columns.Count != objB.Columns.Count) return false;
}
DataView dv = new DataView(objB);
string keys = "";
foreach (DataColumn col in objA.Columns) keys += "," + col.ColumnName;
dv.Sort = keys.Substring(1);
foreach (DataRow row in objA.Rows) {
if (row.RowState != DataRowState.Deleted) {
if (dv.Find(row.ItemArray) < 0) return false;
} else return false;
}
return true;
}
致命缺陷:DataView.Find 依排序鍵值查找,若多行鍵值相同 (如無主鍵、或主鍵非唯一),Find 僅回傳第一筆匹配索引,導致後續不同資料行未被比較。
public bool DataTableTheSame(DataTable Table1, DataTable Table2) {
if (Table1 == null || Table2 == null) return false;
if (Table1.Rows.Count != Table2.Rows.Count) return false;
if (Table1.Columns.Count != Table2.Columns.Count) return false;
for (int i = 0; i < Table1.Rows.Count; i++) {
for (int j = 0; j < Table1.Columns.Count; j++) {
if (Table1.Rows[i][j].ToString() != Table2.Rows[i][j].ToString())
return false;
}
}
return true;
}
優點:逐儲存格比對,邏輯清晰正確,無排序與鍵值依賴問題。
效能考量:小/中型資料集完全足夠;大量資料可考慮雜湊比較或平行處理優化。