前文探討 DataSet 結構與手動填充資料,但實務上需從資料庫批量讀取資料至 DataSet、處理後再批量更新回資料庫,實現離線操作。SqlDataAdapter 正是連接 DataSet 與資料庫的橋樑。
SqlDataAdapter.Fill() 方法自動完成:開啟連線 → 發送 SqlCommand 查詢命令 → 取得結果 → 填充 DataTable → 關閉連線。無需手動呼叫 cn.Open()。
string strSql = "select employeeid,firstname,city,country from Employees";
SqlConnection cn = new SqlConnection(connString);
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand(strSql, cn);
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(ds, "table1"); // 自動建立 table1 並填充資料
GridView1.DataSource = ds.Tables["table1"].DefaultView;
GridView1.DataBind();
SqlDataAdapter da = new SqlDataAdapter(strSql, cn); // 內部自動建立 SqlCommand
da.Fill(ds, "table1");
使用 TableMappings 與 ColumnMappings 將資料庫欄位對應至自訂名稱:
da.TableMappings.Add("employees", "table1"); // 來源表名 -> DataSet 表名
da.TableMappings[0].ColumnMappings.Add("employeeid", "id號");
da.TableMappings[0].ColumnMappings.Add("firstname", "姓名");
da.TableMappings[0].ColumnMappings.Add("city", "城市");
da.TableMappings[0].ColumnMappings.Add("country", "國家");
da.Fill(ds, "employees"); // 來源表名必須與 TableMappings 第一參數一致
執行後 GridView 顯示中文欄位名。來源表名可任意,但 Fill 參數必須一致;DataSet 表名不存在會自動建立。
SqlDataAdapter da = new SqlDataAdapter();
foreach (DataRow dr in ds.Tables["table1"].Rows) {
dr["國家"] = "CHINA"; // 修改 DataSet 中資料
}
da.UpdateCommand = new SqlCommand("update employees set country=@country", cn);
da.UpdateCommand.Parameters.Add("@country", SqlDbType.VarChar, 50, "國家"); // 參數對應 DataTable 欄位
da.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
da.UpdateBatchSize = 9; // 批次更新筆數
da.Update(ds, "table1");
關鍵:Parameters.Add 最後一參數指定 DataTable 欄位名,執行 Update 時自動取該欄值作為參數。
da.InsertCommand = new SqlCommand(
"insert into employees(firstname,city,country,lastname) values(@firstname,@city,@country,@lastname)", cn);
da.InsertCommand.Parameters.Add("@firstname", SqlDbType.VarChar, 50, "姓名");
da.InsertCommand.Parameters.Add("@city", SqlDbType.VarChar, 50, "城市");
da.InsertCommand.Parameters.Add("@country", SqlDbType.VarChar, 50, "國家");
// lastname 不在 DataTable 中,手動指定值
SqlParameter sp = new SqlParameter("@lastname", SqlDbType.VarChar, 50);
sp.Value = "小三";
da.InsertCommand.Parameters.Add(sp);
DataRow dr = ds.Tables["table1"].NewRow();
dr["姓名"] = "張三"; dr["城市"] = "合肥"; dr["國家"] = "中國";
ds.Tables["table1"].Rows.Add(dr);
da.Update(ds, "table1");
string strSql = "update employees set firstname=@firstname,city=@city,country=@country where employeeid=@employeeid";
da.UpdateCommand = new SqlCommand(strSql, cn);
SqlParameter sp = da.UpdateCommand.Parameters.Add("@employeeid", SqlDbType.Int);
sp.SourceColumn = "id號";
sp.SourceVersion = DataRowVersion.Original; // 使用原始值,忽略 DataSet 中修改
SourceVersion.Original 確保 WHERE 條件使用資料庫原始值,防止主鍵被誤改。
Fill(DataSet, startRecord, maxRecords, srcTable) 可指定起始筆數與擷取筆數:
int maxCount = 9; static int pageN = 0;
void bindGridView(int pageN) {
SqlDataAdapter da = new SqlDataAdapter(strSql, cn);
// 設定對映...
da.Fill(ds, pageN, 1, "employees"); // 從第 pageN 筆開始取 1 筆
GridView1.DataSource = ds.Tables["table1"].DefaultView;
GridView1.DataBind();
}
// 上一頁/下一頁按鈕調整 pageN 並重新繫結
效能提醒: 每次翻頁仍需查詢整張表再篩選,資料量大時效能不佳,生產環境建議使用 SQL 分頁(ROW_NUMBER/OFFSET-FETCH)。
SqlDataAdapter 是 DataSet 與資料庫互動的核心,掌握 Fill、Update、參數對映、批次更新與分頁技巧,能構建高效的離線資料操作架構。