1.源由:
工作上的關係。欲處理的資料量滿大的有一萬六千多筆要批次量處理。在速度上必須要特別的處理,不然程式會進入「沒有反應」的狀態。
2.目的, spec. statement.
在處理的資料中,其中一段資料搬移(新增)處理中要先檢是否已存在,不存在才可加入。這時才發現查詢速度必須加速才行。
原先是使用Linq來檢查是否已存在。因速度不夠快,改用DataTable 的Find()成員函式來處理。
3.解法, solution
使用DataTable的Find()成員函式來檢查資料是否已存在。
查看MSDN後,Find()成員函式在使用前須先設定DataTable.PrimaryKey。
參考文章:
DataRowCollection.Find 方法 (Object)
http://msdn.microsoft.com/zh-tw/library/ydd48eyk(VS.80).aspx
DataTable.PrimaryKey Property
http://msdn.microsoft.com/en-us/library/system.data.datatable.primarykey.aspx
4.原碼
下面是本人實戰原碼:
private void btnShiftAddAll_Click(object sender, EventArgs e)
{
try
{
//## UI控制
this.Cursor = Cursors.WaitCursor;
if (gvSource.Rows.Count == 0) return; // 無資料,離開。
DataTable dtSource = gvSource.DataSource as DataTable;
DataTable dtTarget = gvTarget.DataSource as DataTable;
if (dtTarget.PrimaryKey.Length == 0)
{
/// 設定PK以加速Find速度。
dtTarget.PrimaryKey = new DataColumn[] { dtTarget.Columns["ast_num"] };
}
//dtTarget.Merge(dtSource);
//## 若沒有,才加入。
foreach (DataRow shiftRow in dtSource.Rows)
{
// 原先使用Linq Query,因速度不夠,改用別的方法。
///int isExist = dtTarget.AsEnumerable().Count(
/// c => c.Field<string>("ast_num") == shiftRow.Field<string>("ast_num"));
///if (isExist == 0)
DataRow drFind = dtTarget.Rows.Find(shiftRow.Field<string>("ast_num"));
if (drFind == null)
{
dtTarget.ImportRow(shiftRow); // 資料不存在,才加入(移動資料)。
}
}
dtSource.Clear(); //
dtSource.AcceptChanges();
dtTarget.AcceptChanges();
}
finally
{
//## UI控制
this.Cursor = Cursors.Default;
}
}