チュートリアル > クライアント側の実装 > サーバーへの変更のコミットサーバーへの変更のコミット |
ほとんど完成に近づきました。この後は、ユーザーが行った変更がデータベースに適用されるように、変更をサーバーに送信するコードを追加します。
最初の手順は、Page コンストラクタをもう一度変更し、[Commit Changes]ボタンにイベントハンドラを接続します。
コードのコピー
|
|
---|---|
// データをロードし、イベントハンドラを登録します public Page() { InitializeComponent(); LoadData(); _gridCategories.SelectionChanged += _gridCategories_SelectionChanged; _btnAdd.Click += _btnAdd_Click; _btnRemove.Click += _btnRemove_Click; _btnCommit.Click += _btnCommit_Click; } |
次は、イベントハンドラの実装です。
コードのコピー
|
|
---|---|
// 変更をサーバーにコミットします private void _btnCommit_Click(object sender, RoutedEventArgs e) { SaveData(); } |
次は、実際の作業を行う SaveData メソッドの実装です。
コードのコピー
|
|
---|---|
// データベースにデータを戻して保存します void SaveData() { if (_ds != null) { // 各タイプの変更を取得します byte[] dtAdded = GetChanges(DataRowState.Added); byte[] dtModified = GetChanges(DataRowState.Modified); byte[] dtDeleted = GetChanges(DataRowState.Deleted); // サービスを呼び出します var svc = new GetDataService(); svc.UpdateDataCompleted += svc_UpdateDataCompleted; svc.UpdateDataAsync(dtAdded, dtModified, dtDeleted); } } void svc_UpdateDataCompleted(object sender, UpdateDataCompletedEventArgs e) { if (!string.IsNullOrEmpty(e.Result)) { throw new Exception("Error updating data on the server: " + e.Result); } _tbStatus.Text = "変更がサーバーに反映されました。"; _ds.AcceptChanges(); } |
このメソッドは、最初に GetChanges メソッドを呼び出して3つのバイト配列を作成します。各バイト配列は、サーバーからデータがダウンロードされてから、追加、変更、または削除された行を含む DataSet を表します。次に、前に実装した Web サービスを呼び出して、その結果を待ちます。サーバーの更新中にエラーが検出された場合は、例外をスローします(実際のアプリケーションでは、エラーはもう少し丁寧に処理されます)。
残りは GetChanges メソッドです。次にコードを示します。
コードのコピー
|
|
---|---|
byte[] GetChanges(DataRowState state) { DataSet ds = _ds.GetChanges(state); if (ds != null) { MemoryStream ms = new MemoryStream(); ds.WriteXml(ms); return ms.ToArray(); } return null; } |
このメソッドは、DataSet.GetChanges メソッドを使用して、呼び出し元で指定された DataRowState を持つ行のみを含む新しい DataSet オブジェクトを取得します。このメソッドは、ADO.NET DataSet クラスにあるメソッドと同じです。
次に、このメソッドは、変更を含む DataSet を MemoryStream にシリアライズし、ストリームコンテンツをバイト配列として返します。
ここでアプリケーションを実行してみてください。いくつかの変更を行ったら、[Commit Changes]ボタンをクリックして、サーバーに変更を送信します。アプリケーションを終了して再起動すると、実際に、それらの変更がデータベースに保存されていることを確認できます。
![]() |
メモ: 行った変更によっては、更新が失敗することがあります。たとえば、既存のカテゴリの1つを削除した場合、そのカテゴリに属するすべての製品もクライアントの DataSet から削除されます。このような変更をサーバーに適用しようとすると、削除される製品を参照しているテーブル(この例では、Orders テーブル)がまだデータベースに存在している場合があるため、処理が失敗する可能性があります。削除/コミット操作をテストするには、カテゴリを作成し、変更をコミットしてから、その新しいカテゴリを削除し、再度コミットしてください。新しいカテゴリには、関連付けられている製品がデータベース内にまだないため、これは成功します。 |
実際のアプリケーションでは、このような問題を精巧に処理する必要があります。たとえば、Orders テーブルもロードして、DataSet を調査し、削除できない項目をユーザーが削除しようとしていないかどうかを検出して、警告を出すこともできます。これは、読者の練習課題として残しておきます。