DataTable dt1 = this.ClientBLData.DsData.Tables["UserProfile"];
DataTable dt2 = new DataTable();
dt2 = dt1.Clone(); // 僅複製結構
DataRow[] drws = dt1.Select("CostName like '生物%'");
foreach (DataRow item in drws) {
dt2.Rows.Add(item); // ❌ 錯誤:item 屬於 dt1,無法直接添加到 dt2
}
DataRow 物件強綁定其所屬的 DataTable(通過內部 Table 屬性)。嘗試將屬於表 A 的 Row 添加到表 B 會拋出:
System.ArgumentException: This row already belongs to another table.
foreach (DataRow item in drws) {
dt2.Rows.Add(item.ItemArray); // ✅ 正確:傳入 object[] 數值陣列
}
ItemArray 返回該行所有列值的 object[],Rows.Add(object[]) 會在目標表中創建**新行**並填入數值。
foreach (DataRow item in drws) {
dt2.ImportRow(item); // ✅ 專門用於跨表複製行
}
ImportRow 內部會自動處理結構匹配、創建新行、複製數據、保留 RowState(Added)。
// 創建只包含篩選行的 DataTable
DataTable filtered = drws.CopyToDataTable(); // 需引用 System.Data.DataSetExtensions
dt2.Merge(filtered); // 或 dt2.Load(filtered.CreateDataReader());
DataTable dt1 = this.ClientBLData.DsData.Tables["UserProfile"];
DataTable dt2 = dt1.Clone(); // 複製結構(含約束、預設值)
// 篩選
DataRow[] drws = dt1.Select("CostName like '生物%'");
// 方案二:ImportRow(推薦,語義明確)
foreach (DataRow row in drws) {
dt2.ImportRow(row);
}
// 綁定 UI
KSDataGrid2.ItemsSource = dt2.DefaultView;
// 目標表僅包含部分列
DataTable dtTarget = new DataTable();
dtTarget.Columns.Add("CostName", typeof(string));
dtTarget.Columns.Add("Amount", typeof(decimal));
foreach (DataRow srcRow in drws) {
DataRow newRow = dtTarget.NewRow();
newRow["CostName"] = srcRow["CostName"];
newRow["Amount"] = srcRow["Amount"]; // 列名相同可直接賦值
dtTarget.Rows.Add(newRow);
}
| 方法 | 耗時(ms) | 記憶體 | 備註 |
|---|---|---|---|
| foreach + ItemArray | ~120 | 低 | 通用、兼容性好 |
| foreach + ImportRow | ~110 | 低 | 語義最清晰,推薦 |
| CopyToDataTable + Merge | ~80 | 中 | 大批量最快,需引用擴展程序集 |
| Load(IDataReader) | ~70 | 低 | 流式處理,記憶體效率最高 |
Clone() 僅複製結構,Copy() 複製結構+數據DataRow[] 仍屬於原表,非獨立副本跨 DataTable 複製行的核心原則:**數值傳遞,而非物件傳遞**。使用 ImportRow 或 ItemArray 讓目標表創建自己的行實例,是穩健、高效、語義正確的做法。