チュートリアル : 関連するデータ テーブルからのデータの保存 (階層更新)

アプリケーション上のデータをデータベースに保存し直すのは、データのテーブルが 1 つだけの場合や、外部キー制約を考慮する必要がない場合は非常に簡単です。しかし、複数のデータ テーブルが関連し合うデータセットからデータを保存する場合は、制約に違反しない順番で変更内容をデータベースに送信する必要があります。関連テーブルで変更したデータを更新するには、各データ テーブルからデータのサブセットを抽出し、正しい順番でデータベースに更新を送信するプログラム ロジックを用意します。または、TableAdapterManager コンポーネントを使用するという方法もあります。

このチュートリアルでは、TableAdapterManager コンポーネントを使用して関連データを保存する方法について説明します。手動による関連データ テーブル更新のコーディングについては、「チュートリアル : データベースへのデータの保存 (複数テーブル)」を参照してください。

必須コンポーネント

このチュートリアルを完了するには、次の条件が必要です。

Windows ベース アプリケーションの作成

このチュートリアルでは、まず、新しい Windows ベースのアプリケーションを作成します。

新しい Windows ベースのアプリケーションを作成するには

  1. [ファイル] メニューで新しいプロジェクトを作成します。

    [!メモ]

    階層更新は、Visual Basic プロジェクトと C# プロジェクトでサポートされる機能です。新しいプロジェクトはこのどちらかの言語で作成してください。

  2. プロジェクトに HierarchicalUpdateWalkthrough という名前を付けます。

  3. [Windows フォーム アプリケーション] をクリックし、[OK] をクリックします。詳細については、「クライアント アプリケーションの開発」を参照してください。

    HierarchicalUpdateWalkthrough プロジェクトが作成されてソリューション エクスプローラーに追加されます。

データセットの作成

階層更新を実行するには関連テーブルが必要なので、次に、Northwind データベースの Customers テーブルと Orders テーブルを含むデータセットを作成します。データ ソース構成ウィザードを実行して、データセットを作成します。接続を作成するには、Northwind サンプル データベースにアクセスできる必要があります。Northwind サンプル データベースの設定方法については、「方法 : サンプル データベースをインストールする」を参照してください。

データセットを作成するには

  1. [データ] メニューの [データ ソースの表示] をクリックします。

  2. [データ ソース] ウィンドウで、[新しいデータ ソースの追加] をクリックしてデータ ソース構成ウィザードを起動します。

  3. [データ ソースの種類を選択] ページで、[データベース] をクリックし、[次へ] をクリックします。

  4. [データ接続の選択] ページで、次のいずれかの操作を行います。

  5. データベースにパスワードが必要な場合は、該当するオプションを選択して重要情報を含め、[次へ] をクリックします。

  6. [アプリケーション構成ファイルに接続文字列を保存] ページで、[次へ] をクリックします。

  7. [データベース オブジェクトの選択] ページの [テーブル] ノードを展開します。

  8. Customers テーブルと Orders テーブルに該当するチェック ボックスをオンにし、[完了] をクリックします。

    プロジェクトに NorthwindDataSet が追加され、[データ ソース] ウィンドウにこれら 2 つのテーブルが表示されます。

作成される既定のデータ バインド コントロールの変更

[データ ソース] ウィンドウでデータ ソースを設定したら、次に、Windows フォームに項目をドラッグしたときに作成されるコントロールを選択します。このチュートリアルでは、Customers テーブルのデータを個別のコントロール ([詳細]) で表示します。Orders テーブルのデータは、DataGridView コントロール (DataGridView) に表示します。

[データ ソース] ウィンドウの項目に対してコントロールを設定するには

  1. [データ ソース] ウィンドウの [Customers] ノードを展開します。

  2. [Customers] ノードのコントロール リストで [詳細] をクリックし、Customers テーブルに対して作成されるコントロールを個別のコントロールに変更します。詳細については、「方法 : [データ ソース] ウィンドウからドラッグしたときに作成されるコントロールを設定する」を参照してください。

    [!メモ]

    Orders テーブルは、既定のコントロール DataGridView を使用します。

データ バインド フォームの作成

[データ ソース] ウィンドウでコントロールを選択したら、フォームに項目をドラッグして、データ バインド コントロールを作成します。

Customers データと Orders データのデータ バインド コントロールを作成するには

  1. [データ ソース] ウィンドウから Form1 にメインの [Customers] ノードをドラッグします。

    説明のラベルが付いたデータ バインド コントロールが、レコード間を移動するためのツール バー (BindingNavigator) である TableAdapterManager コンポーネントと共にフォーム上に表示されます。型指定された DataSetTableAdapter、および BindingSource がコンポーネント トレイに表示されます。

  2. [データ ソース] ウィンドウから Form1[Orders] ノードをドラッグします。

    [!メモ]

    関連する [Orders] ノードは Customers テーブルの [Fax] ノードの下にあり、[Customers] ノードの子ノードです。[Customers] ノードのピアとして表示される [Orders] ノードは、Orders テーブル内のすべての注文を表します。[Customers] ノードの子ノードとして表示される [Orders] ノードは、関連する注文を表します。

    DataGridView とレコード間をナビゲートするためのツール バー (BindingNavigator) がフォームに表示されます。コンポーネント トレイには TableAdapterBindingSource が表示されます。

階層更新を実行するように生成された保存コードの変更

データセットでの関連データ テーブルへの変更をデータベースに保存するには、TableAdapterManager.UpdateAll メソッドを呼び出し、関連テーブルが含まれるデータセットの名前を渡します。たとえば、NorthwindDataset 内の全テーブルの更新をバックエンドのデータベースに送信するには、TableAdapterManager.UpdateAll(NorthwindDataset) メソッドを実行します。

[データ ソース] ウィンドウから項目をドラッグすると、各テーブルを読み込むコード (TableAdapter.Fill メソッド) が、Form_Load イベントに自動的に追加されます。また、BindingNavigator[保存] ボタン クリック イベントにも、データセットのデータをデータベースに保存するコード (TableAdapterManager.UpdateAll メソッド) が追加されます。

生成された保存コードには、CustomersBindingSource.EndEdit メソッドを呼び出すコード行も含まれています。これは、具体的には、フォームに最初に追加された BindingSourceEndEdit メソッドを呼び出します。つまり、このコードは [データ ソース] ウィンドウからフォームに最初にドラッグしたテーブルに対してのみ生成されます。EndEdit 呼び出しは、現在編集中のデータ バインド コントロールで実行されている変更をコミットします。したがって、あるデータ バインド コントロールにフォーカスがある状態で、[保存] ボタンをクリックすると、実際の保存 (TableAdapterManager.UpdateAll メソッド) が実行される前に、そのコントロール内のすべての保留中の編集がコミットされます。

[!メモ]

デザイナーは、フォームに最初にドロップされたテーブルに対してのみ BindingSource.EndEdit コードを追加します。したがって、フォーム上の各関連テーブルに対しては BindingSource.EndEdit メソッドを呼び出すコードを手動で追加する必要があります。つまり、このチュートリアルでも、OrdersBindingSource.EndEdit メソッドの呼び出しを追加する必要があります。

保存前に、関連テーブルへの変更をコミットするコードを更新するには

  1. BindingNavigator[保存] ボタンをダブルクリックし、コード エディターに Form1 を開きます。

  2. CustomersBindingSource.EndEdit メソッドを呼び出す行の後に、OrdersBindingSource.EndEdit メソッドを呼び出すコード行を追加します。[保存] ボタン クリック イベント内のコードは、次のようになります。

    Me.Validate()
    Me.CustomersBindingSource.EndEdit()
    Me.OrdersBindingSource.EndEdit()
    Me.TableAdapterManager.UpdateAll(Me.NorthwindDataSet)
    
    this.Validate();
    this.customersBindingSource.EndEdit();
    this.ordersBindingSource.EndEdit();
    this.tableAdapterManager.UpdateAll(this.northwindDataSet);
    

データをデータベースに保存する前に関連子テーブルに対する変更をコミットするだけではなく、新しい子レコードをデータセットに追加する前に、新しく作成された親レコードをコミットすることが必要な場合もあります。つまり、外部キー制約により、新しい子レコード (Orders) をデータセットに追加する前に、データセットに新しい親レコード (Customer) を追加することが必要な場合もあります。この操作を行うには、子 BindingSource.AddingNew イベントを使用します。

[!メモ]

新しい親レコードをコミットする必要があるかどうかは、データ ソースのバインドに使用されるコントロールの種類によって決定されます。このチュートリアルでは、親テーブルとのバインドに個別のコントロールを使用するので、新しい親レコードをコミットするコードを追加する必要があります。親レコードが DataGridView のような複雑なバインド コントロールに表示される場合には、親レコードに対する EndEdit 呼び出しは必要ありません。これは、コントロールの基になるデータ バインド機能が、新しいレコードのコミットを行うためです。

データセットで新しい子レコードを追加する前に親レコードをコミットするコードを追加するには

  1. OrdersBindingSource.AddingNew イベントのイベント ハンドラーを作成します。

    • デザイン ビューで Form1 を開いて、コンポーネント トレイの OrdersBindingSource をクリックし、[プロパティ] ウィンドウで [イベント] を選択して、AddingNew イベントをダブルクリックします。
  2. CustomersBindingSource.EndEdit メソッドを呼び出すコード行をイベント ハンドラーに追加します。OrdersBindingSource_AddingNew イベント ハンドラー内のコードは、次のようになります。

    Me.CustomersBindingSource.EndEdit()
    
    this.customersBindingSource.EndEdit();
    

階層更新の有効性の確認

階層更新は、データセットの "階層更新" プロパティを設定することにより、有効または無効にできます。階層更新は、既定で有効になっているため、このチュートリアルで、"階層更新" プロパティ値を変更する必要はありません。

階層更新が有効かどうかを確認するには

  1. ソリューション エクスプローラーNorthwindDataSet.xsd ファイルをダブルクリックして、データセット デザイナーにこのデータセットを開きます。

  2. デザイン サーフェイス上の空の領域を選択します。

  3. [プロパティ] ウィンドウ"階層更新" プロパティを見つけ、これが True に設定されているかどうかを確認します。

    [!メモ]

    "階層更新" プロパティは、TableAdapterManager と、階層更新を実行するロジックでコードを生成するかどうかを制御します。階層更新True に設定すると、TableAdapterManager が生成され、"階層更新"False に設定すると、TableAdapterManager は生成されません。

アプリケーションのテスト

アプリケーションをテストするには

  1. F5 キーを押します。

  2. 各テーブルの 1 つ以上のレコードのデータを変更します。

  3. 新しい顧客を追加し、次に、この顧客に対して新しい注文を追加します。

  4. [データの保存] をクリックします。TableAdapterManager が、関連する更新すべてに必要なロジックを処理します。

  5. データベースの値をチェックし、変更が各テーブルに保存されたことを確認します。

次の手順

Windows ベース アプリケーションに関連データを保存した後で、アプリケーションの要件によってはさらに操作を追加する必要があります。このアプリケーションで行うことができる拡張には次のものがあります。

  • 3 番目のテーブル (OrderDetails テーブルなど) を追加し、3 番目のテーブル階層を試してみる。

  • データベース制約に加えて、データがアプリケーション要件を満たしているかどうかを検証する検証コードを追加する。詳細については、「データの検証」を参照してください。

参照

処理手順

方法 : データセットでの外部キー制約を構成する

方法 : 階層更新の実行順序を設定する

方法 : データの保存前にデータ バインド コントロールで実行中の編集をコミットする

方法 : 既存の Visual Studio プロジェクトで階層更新を実装する

チュートリアル : 関連するデータ テーブルからのデータの保存 (階層更新)

概念

データの保存

その他の技術情報

階層更新

DataSets in ADO.NET