在 Windows Forms 應用程式中使用 DataGridView 顯示並編輯 Access 資料庫資料,雖然介面上修改了資料,但呼叫 OleDbDataAdapter.Update 後資料庫並未同步更新,且未拋出明顯例外。
string connstr = "Provider=Microsoft.Jet.OleDb.4.0;";
connstr += @"Data Source=D:\Merger201503016caohuan\GEARCNC.mdb";
OleDbConnection tempconn = new OleDbConnection(connstr);
tempconn.Open();
OleDbDataAdapter DressingWheelDA = new OleDbDataAdapter(
"select * from DressingWheel order by 修整輪名稱", tempconn);
DataSet ds = new DataSet();
DressingWheelDA.Fill(ds, "DressingWheel");
OleDbCommandBuilder builder = new OleDbCommandBuilder(DressingWheelDA);
if (ds.HasChanges())
{
try
{
DressingWheelDA.Update(ds, "DressingWheel");
}
catch (Exception ex)
{
MessageBox.Show("修整輪名稱重複", "信息提示");
}
}
ex.Message 被忽略,導致無法得知實際失敗原因(如主鍵衝突、欄位型別不符、資料庫鎖定等)。OleDbCommandBuilder 需要資料表有主鍵才能自動產生 UPDATE/DELETE 指令。若 DressingWheel 資料表無主鍵,builder 將無法生成有效命令,Update 會靜默失敗。DataGridView 編輯結束時需呼叫 EndEdit 或確認 BindingSource.EndEdit,否則 ds.HasChanges() 可能為 false。catch (Exception ex)
{
MessageBox.Show($"更新失敗:{ex.Message}\n堆疊:{ex.StackTrace}", "錯誤");
// 或寫入 Log 檔案
}
在 Access 中為 DressingWheel 設定主鍵(如 ID 欄位)。若無法修改資料庫結構,請手動設定 UpdateCommand:
builder = new OleDbCommandBuilder(DressingWheelDA);
// 檢查自動生成的命令
Console.WriteLine(builder.GetUpdateCommand().CommandText);
// 在呼叫 Update 前
dataGridView1.EndEdit(); // 若直接繫結 DataGridView
bindingSource1.EndEdit(); // 若使用 BindingSource
確認 .mdb 檔案未設為「唯讀」,且執行身分有寫入權限。建議將資料庫放在 AppData 或專案輸出目錄下。
private void SaveData()
{
try
{
this.Validate(); // 觸發驗證
this.bindingSource1.EndEdit(); // 提交編輯
if (ds.HasChanges())
{
int rows = DressingWheelDA.Update(ds, "DressingWheel");
MessageBox.Show($"成功更新 {rows} 筆資料");
}
else
{
MessageBox.Show("無資料變更");
}
}
catch (OleDbException odbEx)
{
MessageBox.Show($"資料庫錯誤:{odbEx.Message}", "錯誤");
}
catch (Exception ex)
{
MessageBox.Show($"系統錯誤:{ex.Message}", "錯誤");
}
}
DataGridView 資料不回寫資料庫,最常見原因是 例外被吞沒、資料表缺主鍵導致 CommandBuilder 失效、編輯未提交。優先加上詳細錯誤訊息、確認主鍵存在、呼叫 EndEdit,即可解決 90% 以上案例。