チェックボックスの状態によって、 DB を更新するかしないかを簡単に決める方法
昨日の続きですが、 GridView などにチェックボックスを表示し、チェックされた複数行を一括更新したいときがあります。そんなときは、以下のようなユーティリティメソッドを用意しておくと便利です。
/// <summary> /// 無駄な更新が発生しないように DataRowState を補正 /// </summary> /// <param name="table">更新予定の DataTable</param> /// <param name="checkBoxColumn">チェックボックスの状態を保持した DataColumn (型は bool であること)</param> /// <remarks> /// このユーティリティメソッドは、チェックボックスを考慮しながら行の編集状態を調査し、 /// 更新の必要がない DataRow の DataRowState を Unchanged にもどす /// </remarks> public static void CorrectDataRowState(DataTable table, DataColumn checkBoxColumn) { foreach (DataRow row in table.Rows) { if (!HasChanges(row, checkBoxColumn)) row.RejectChanges(); } } /// <summary> /// DataRow が変更されているかをチェック /// </summary> /// <param name="row">DataRow</param> /// <param name="checkBoxColumn">チェックボックスの状態を保持した DataColumn (型は bool であること)</param> /// <returns>変更されていれば true, 変更がなければ false</returns> private static bool HasChanges(DataRow row, DataColumn checkBoxColumn) { // 追加や削除の場合は無条件で編集あり if (row.RowState == DataRowState.Added || row.RowState == DataRowState.Deleted || row.RowState == DataRowState.Detached) return true; // チェックがついていないレコードは編集なしとみなす // NOTE: DataRowState.Deleted の場合にエラーになるため、 // チェックボックスは最後に確認 if (row.RowState == DataRowState.Unchanged || !(bool)row[checkBoxColumn]) return false; // DataRowState.Modified の場合は、各列の内容に変更があるかをチェック foreach (DataColumn column in row.Table.Columns) { // チェックボックス列は比較しない if (!(column == checkBoxColumn || row[column].Equals(row[column, DataRowVersion.Original]))) return true; } // 値が全て同じなら編集していないと見なす return false; }
使用側は、以下のように更新メソッドを呼び出す前に CorrectDataRowState() を呼び出します。
// データを取得 CountryDataTable table = GetData(); // 更新される table[0].Checked = true; table[0].Name = "New Name"; // 更新されない (更新対象のチェックボックスが OFF なので) table[1].Checked = false; table[1].Name = "New Name"; // 更新されない (Name に同じ値が設定されたため) table[2].Checked = true; table[2].Name = table[2].Name; CorrectDataRowState(table, table.CheckedColumn); // RowState を考慮しながら table の中身を更新 // NOTE: 通常であれば table[2] の RowState が Modified になる。 // しかし、 CorrectDataRowState() によって RowState が補正されるため、無駄な更新が発生しない。 Update(table);