更新日: 2005 年 11 月 1 日

このコンテンツのポイント

  • データ ソース構成ウィザードの使用方法
  • DataSet の使用方法
  • DataSet と XMLファイルとの相互変換の方法

今回紹介するコード

Visual Basic
Private Sub Form1_Load(ByVal sender As System.Object, _
                        ByVal e As System.EventArgs) Handles MyBase.Load
    Dim result As DialogResult
    result = MessageBox.Show("サーバーからデータを取得しますか?" , _
                             "データのロード", MessageBoxButtons.YesNo)
    If result = DialogResult.Yes Then
        'TODO: このコード行はデータを 'AdvDataSet.PurchaseOrderDetail' テーブルに... 
        Me.PurchaseOrderDetailTableAdapter.Fill(Me.AdvDataSet.PurchaseOrderDetail)
        'TODO: このコード行はデータを 'AdvDataSet.PurchaseOrderHeader' テーブルに... 
        Me.PurchaseOrderHeaderTableAdapter.Fill(Me.AdvDataSet.PurchaseOrderHeader)
    Else
        AdvDataSet.ReadXml("C:\Test\MyCache.xml")
    End If
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button1.Click
    'データセットの内容を XML ファイルとして退避
    AdvDataSet.WriteXml("C:\Test\MyCache.xml")
End Sub
 

 

目次

はじめに
作成するアプリケーションの概要
Windows アプリケーションの開発準備をする
データ ソースを構成する
ユーザー インターフェイスを自動生成する
実行する
もう一つのユーザー インターフェイスを追加する
実行する
コードを実装する
実行する
おわりに


 

はじめに

ADO.NET の高機能なクラス ライブラリと Visual Studio 2005 のビジュアルなデザイン環境を使用すると、リレーショナル データベースや XMLデータの操作に対して、共通のライブラリを使って、効率よくアプリケーション開発を行うことができます。今回は、データベースとの接続を切断してデータをメモリにキャッシュするデータセットの操作や、そのデータセットと XML データとの間でのデータ変換を行う処理などを含む、Windows フォーム アプリケーションを作成します。

作成するアプリケーションの概要

今回は、Visual Studio 2005 を使用して、Windows フォーム アプリケーションを作成します。 データベースのエンジンとしては、Visual Studio 2005 に付属の SQL Server 2005 Express Edition (SQL Server Express) を使用します。また、データベースとしては、SQL Server 2005 に付属の 「AdventureWorks」 サンプル データベース ファイルを使用します。(SQL Server 2000 の "pubs" データベースや "Northwind" データベースでも、今回の操作を行うことができます。データベースの中に、親子関係の二つのテーブルがあれば、以下の操作を行うことができます。) ここで作成する Windows フォームでは、1対多の関係にある二つのテーブルの内容を、マスタ/詳細形式で表示するようにします。

Windows アプリケーションの開発準備をする

Visual Studio 2005 を起動して、新しいプロジェクトを作成します([ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします)。ここでは、プロジェクトの種類ペインで [Visual Basic] を選択し、テンプレート ペインで、[Windows アプリケーション] を選択します。[プロジェクト名] ボックスに 「DBApp」 と入力します。[場所] ボックスには、「C:\Test」 というパスを入力します。 ここで、[OK] ボタンをクリックして、プロジェクトを作成します。

これで、今回のアプリケーションの開発準備が完了しました。

図 1. Windows アプリケーション プロジェクトを新規に作成する

 

データ ソースを構成する

この後の作業は、コード エディタ (テキスト エディタ) を使って、ADO.NET を使用するコードを1行ずつ書いて実装することもできます。ここでは、Visual Studio 2005 の便利な機能をいくつか使って作成します。その一つが [データ ソース] ウィンドウです。[データ ソース] ウィンドウには、そのアプリケーションで使用するデータセットの管理や、データ アクセスに関する様々なコードの管理を行う機能があります。

まず、[データ] メニューから [データ ソースの表示] をクリックします。図2 のような [データ ソース] ウィンドウを表示します。

図 2. [データ ソース] ウィンドウ

 

ここでは、親子関係にある二つのテーブルにアクセスするアプリケーションを作ります。まずは、以下の操作を行って、二つのテーブルをキャッシュするデータセットと、関連するデータ操作を行うコードを生成します。 [データ ソース] ウィンドウの左端にある [新しいデータ ソースの追加] ボタンをクリックします。(ボタンの名称は、マウスポインタをボタンの上に移動することで、ツールヒントとして表示されます。) すると、データ ソース構成ウィザードが起動します。(図3)

図3. データ ソース構成ウィザード

 

図3 では、[データ ベース] を選択して、[次へ] ボタンをクリックします。

図4 のように、データ接続を選択する画面になるので、画面の右側にある [新しい接続] ボタンをクリックします。

図4. データ接続を選択する

 

図5 のように、[接続の追加] ダイアログ ボックスが開くので、利用可能なサンプル データベースを指定します。親子関係にある二つのテーブルを持つデータベースであれば、今回の作業ではデータベースを問いません。

ここでは、プログラム実行時に AdventureWorks のデータベース ファイルをSQL Server Express へアタッチすることにします。AdventureWorks データベース ファイルは、あらかじめ SQL Server 2005 からデタッチして、C:\Test\_DB に置いておきます。図5 のように、[データ ソース] 欄では「SQL Server データベース ファイル」を指定し、[データベース ファイル名] 欄では「C:\Test\_DB\AdventureWorks_Data.mdf」と指定しています。[Windows 認証を使用する] オプションを選択して、[OK] をクリックします。

図5. 接続するデータベースを指定する

 

図4 のデータ接続の選択画面に戻るので、[次へ] をクリックします。前述のように、データベース ファイルを指定した場合、プロジェクト内にコピーするか問い合わせが表示されるので (図6) 、[いいえ] をクリックします。

図6. プロジェクト内にコピーするか問い合わせが表示される

 

次に、データベースにアクセスするための接続文字列を、アプリケーション構成ファイルに保存するか問い合わせが表示されます (図7)。Visual Studio 2005 では、接続文字列はソース コードに書かずに、アプリケーション構成ファイルに切り分けることが可能です。これによって、アプリケーションの運用時に後から接続先を変えるとき、コー ド修正や再コンパイルをせずに、構成ファイルを変更するだけで済みます。[次の名前で接続を保存する] チェックボックスをチェックしたままにして、[次へ] をクリックします。

図7. 接続文字列は、アプリケーション構成ファイルに保存できる

 

次に、データベース オブジェクトを選択する画面になるので (図8)、その画面のツリー上にある [テーブル] ノードを展開し、親テーブルとして、[PurchaseOrderHeader] テーブルの [PurchaseOrderID] 列、[EmployeeID] 列、[OrderDate] 列、および [TotalDue] 列をチェックし (図8)、子テーブルとして、[PurchaseOrderDetails] テーブルの [PurchaseOrderID] 列、[PurchaseOrderDetailID] 列、[OrderQty] 列、[ProductID] 列、および [UnitPrice] 列をチェックします。(注: このウィザードに二つのテーブルの関係を認識させる必要があるので、あらかじめ、データベースには、二つのテーブル間に 1対多のリレーションが設定されていなければなりません。) また、[データセット名] のボックスには、「AdvDataSet」 と指定します。

図8. 親テーブルを指定する

 

図9. 子テーブルを指定するる

 

ウィザードが終了すると、[データ ソース] ウィンドウには、指定した二つのテーブルが表示されます。(図10)

図10. データセット AdvDataSet の構造が表示される

 

図10 は、生成されたデータセットの構造を表しており、ルートノードの「AdvDataSet」は、このデータセットのクラス名です。このクラスは、 DataSet クラスから派生したクラスで、二つのテーブルをキュッシュするための専用のデータ構造が定義されています。既定では、このクラスのソース ファイルは、ソリューション エクスプローラのツリーに表示されません。ソリューション エクスプローラ上部の [すべてのファイルを表示] ボタンを押すと表示できます。[AdvDataSet.xsd] ファイル ノードの下の、AdvDataSet.Designer.vb ファイル (図11) に AdvDataSet クラスの定義があります。

図11. データセット AdvDataSet クラスのソース コードのファイルが生成される

 

また、[データ ソース] ウィンドウの各テーブル ノードを展開すると、各テーブルの列名が分かります。また、[PurchaseOrderHeader] テーブルのノードの配下には、さらに [PurchaseOrderDetails] ノードがあります。これは、親テーブル [PurchaseOrderHeader] と子テーブル [PurchaseOrderDetails] の関係 (一対多) を表しています。

図12. 列名やテーブル間の関係が表示される

 

ユーザー インターフェイスを自動生成する

[データ ソース] ウィンドウは、フォームからデータ ソースにアクセスするための、ユーザー インターフェイスを生成する機能も備えています。[データ ソース] ウィンドウから Windows フォーム デザイナへ、テーブルをドラッグ アンド ドロップすると、そのテーブルに連結したコントロールが、フォームに生成されるのです。

その際、フォーム上に生成されるコントロールの種類を予め指定することができます。ここでは、テーブル [PurchseOrderHeader] の全体を DataGridView コントロールとして表示するのではなく、列ごとの異なるコントロールになるように設定します。図13 のように、[PurchaseOrderHeader] のドロップダウン リストから、[詳細] をクリックします。

図13. [PurchaseOrderHeader] の列ごとに、コントロールが異なるように設定する

 

設定が済んだら、[データ ソース] ウィンドウから [PurchaseOrderHeader] テーブルを、Windows フォーム デザイナ上にドラッグ アンド ドロップします。すると、このテーブルに列ごとにコントロールが生成されます。また、フォームの上部には、レコードを移動するための BindingNavigator コントロールが追加されています。(図14)

図14. テーブル PurchaseOrderHeader と連結したコントロールが自動生成される

 

なお、生成されたコントロールのうち、[Order Data] 列は DateTimePicker が使用されています。これは、[データ ソース] ウィンドウ側で、日付型の既定値として、DateTimePicker コントロールを使用するよう設定されていたからです。(図15)

図 15. 日付入力用の DateTimePicker も指定できる

 

実行する

ここまでの段階で、一旦実行してみます。 [Ctrl] +[ F5] キーを押すか、[デバッグ] メニューの [デバッグなしで開始] をクリックします。すると、データセットにデータがロードされ、そのデータは、データ連結されたコントロールに表示されます。(図16)

図16. PurchaseOrderHeader テーブルの内容が表示される

 

もう一つのユーザー インターフェイスを追加する

今度は、PurchaseOrderHeader テーブルの各レコードに対する明細を表示するために、PurchaseOrderDetails テーブル用のコントロールを追加します。今回は、既定の DataGridView コントロールを使用するので、コントロールの種類は変更しません。ここで、[データ ソース] ウィンドウから PurchaseOrderHeader ノードの下にある PurchaseOrderDetails を、フォームの下半分へドロップします。(注: ルート ノードの直下にある PurchaseOrderDetails をドラッグ アンド ドロップするのではなく、必ず PurchaseOrderHeader ノードの下にある PurchaseOrderDetails を使用してください。さもないと、コード生成の際、二つのテーブルの親子関係が認識されません。)

すると、DataGridView コントロールがフォームに追加されます。(図17)

図17. 子テーブル (明細) を追加する

 

ここでソース コードを確認してみます。フォームの余白をダブルクリックして、Form1_Load イベント ハンドラを表示します。以下のように、Me.PurchaseOrderDetailTableAdapter と Me.PurchaseOrderHeaderTableAdapter の二つの TableAdapter オブジェクトの Fill メソッドを呼び出して、データセット Me.AdvDataSet 内の各テーブルにデータをロードしています。TableAdapter オブジェクトは、Visual Studio 2005 によって自動生成されたオブジェクトで、DataAdapter などの操作をカプセル化したデータ アクセス用のコンポーネントです。

 

Visual Basic
Private Sub Form1_Load(ByVal sender As System.Object, _
                        ByVal e As System.EventArgs) Handles MyBase.Load
    'TODO: このコード行はデータを 'AdvDataSet.PurchaseOrderDetail' テーブルに読み込みます。
    Me.PurchaseOrderDetailTableAdapter.Fill(Me.AdvDataSet.PurchaseOrderDetail)
    'TODO: このコード行はデータを 'AdvDataSet.PurchaseOrderHeader' テーブルに読み込みます。
    Me.PurchaseOrderHeaderTableAdapter.Fill(Me.AdvDataSet.PurchaseOrderHeader)
End Sub
 

実行する

ここで、一旦実行してみます。 [Ctrl] +[ F5] キーを押すか、[デバッグ] メニューの [デバッグなしで開始] をクリックします。今度は、マスタ/詳細形式で表示され、ナビゲーション バーを使って、 PurchaseOrderHeader のレコードを移動すると、そのレコードの明細が下半分の DataGridView に表示されます。(図18) 移動に伴い、上半分の PurchaseOrderHeader の Purchase Order ID と、下半分の明細の PurchaseOrderID が同じ値になるよう、明細が変化する点に注目してください。

図18. マスタ/詳細形式の表示

 

コードを実装する

今度は、データセットのデータをローカル ディスク上に XML データとして退避するコードを実装します。また、Load イベント ハンドラでは、データベースからデータを取得するか、それとも、退避した XML データをロードするか、利用者に対して問い合わせをするようにします。データベース サーバーにアクセスできない環境でも、このアプリケーションはオフラインでデータを利用できるようになります。

まず、図19のように、フォームに Button コントロールを追加し、Text プロパティを「すべてを保存」にします。

図19. ボタンを追加する

 

次に、このボタンをダブルクリックして Click イベント ハンドラを生成させ、Form1_Load イベント ハンドラと Button1_Click イベント ハンドラを以下のように書き換えます。

もともとの Form1_Load イベント ハンドラ内の二つの Fill メソッド呼び出し部分は、If ブロックの中へ移動します。また、Form1_Load イベント ハンドラの先頭では、メッセージ ボックスを表示して、データ ベースからデータを取得するか、それともローカル ディスクからロードするかを問うようにします。Else ブロックでは、データセット AdvDataSetの ReadXml メソッドを呼び出して、ローカルディスクからデータを読み込みます。

一方、Button1_Click イベント ハンドラでは、データセットの AdvDataSet の WriteXml を呼び出して、データセットの内容を、ディスクに書き込んでいます。ReadXml メソッドと WriteXml メソッドは、もともと DataSet クラスのメソッドであり、データセットと XML データとの相互変換を簡単に行うことができます。

Visual Basic
Else
        AdvDataSet.ReadXml("C:\Test\MyCache.xml")
    End If
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button1.Click
    'データセットの内容を XML ファイルとして退避
    AdvDataSet.WriteXml("C:\Test\MyCache.xml")
End Sub
 

(注: ここでは簡単にするため、メッセージボックスの内容やファイルパスを、ソースコードに埋め込んでいます。本来であれば、保守性を向上させるために、これらの文字列はソースファイルから分離して、構成ファイルやリソース ファイルに保存すべきです。)

実行する

ここで、一旦実行してみます。 [Ctrl] +[ F5] キーを押すか、[デバッグ] メニューの [デバッグなしで開始] をクリックします。今度は、フォームが表示される前に、メッセージボックスが表示されます。(図20)

図20. データをデータベース サーバーから取得するか、問い合わせが表示される

 

このメッセージ ボックスでは [はい] を押してデータをロードします。今までどおり、データセットにデータがキャッシュされ、表示されます。(図21)

図21. 1件目のデータが表示される (日付は5月17日)

 

ここで、1件目のデータの日付 5月17日を、5月31日に変更して、[すべてを保存] ボタンを押して、データセットの内容を XML データとして保存します。一旦、アプリケーションを終了します。

保存された C:\Test\MyCache.xml を、エクスプローラから Visual Studio 2005 にドラッグ アンド ドロップして開いて確認します。今回のサンプル データベースでは、XML のファイル サイズがやや大き目なので、開く際に多少時間がかかるかもしれません。図22 のような内容が確認できます。

図22. データセットは XML データとして保存できる

 

再び、アプリケーションを起動して、メッセージ ボックスでは [いいえ] を押して、XML データをデータセットにロードします。(今回のサンプルは件数が多いので、少々時間がかかるかも知れません。) すると、先に変更されたとおり、1件目の データの日付は、5月31日になっています。(図23)

図23. ローカル ディスクから復元した1件目が表示される (日付は5月31日)

 

おわりに

以上、ADO.NET と Visual Studio 2005 を利用して、非接続型のデータセットを生かしたアプリケーションの作り方を見てきました。さらに、データセットと XML データが相互に簡単に変換する方法を確認しました。ここでは、Visual Studio 2005 の機能を活用するという観点から、ADO.NET の実装方法を見ました。Visual Studio 2005 を使用すると、ADO.NET の機能を生かしたアプリケーションを、ビジュアルに効率よく作成することができます。

なお、「ADO.NET によるデータの取得」では、ウィザード類でコード生成せずに、ADO.NET の基本的なクラスを使用するコードを書いて、その機能を確認します。


Code Recipe

ページのトップへ