Data for Silverlight
サーバーへの変更のコミットサーバーへの変更のコミット

ほとんど完成に近づきました。この後は、ユーザーが行った変更がデータベースに適用されるように、変更をサーバーに送信するコードを追加します。

最初の手順は、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 クラスにあるメソッドと同じです。

次に、このメソッドは、変更を含む DataSetMemoryStream にシリアライズし、ストリームコンテンツをバイト配列として返します。

ここでアプリケーションを実行してみてください。いくつかの変更を行ったら、[Commit Changes]ボタンをクリックして、サーバーに変更を送信します。アプリケーションを終了して再起動すると、実際に、それらの変更がデータベースに保存されていることを確認できます。

メモ: 行った変更によっては、更新が失敗することがあります。たとえば、既存のカテゴリの1つを削除した場合、そのカテゴリに属するすべての製品もクライアントの DataSet から削除されます。このような変更をサーバーに適用しようとすると、削除される製品を参照しているテーブル(この例では、Orders テーブル)がまだデータベースに存在している場合があるため、処理が失敗する可能性があります。削除/コミット操作をテストするには、カテゴリを作成し、変更をコミットしてから、その新しいカテゴリを削除し、再度コミットしてください。新しいカテゴリには、関連付けられている製品がデータベース内にまだないため、これは成功します。

実際のアプリケーションでは、このような問題を精巧に処理する必要があります。たとえば、Orders テーブルもロードして、DataSet を調査し、削除できない項目をユーザーが削除しようとしていないかどうかを検出して、警告を出すこともできます。これは、読者の練習課題として残しておきます。

関連トピック

 

 


Copyright © GrapeCity inc. All rights reserved.