第2回 データセットとデータテーブル:連載:Visual Studio 2005によるWindowsデータベース・プログラミング(3/3 ページ)
データセットを経由してDBにアクセスするのが.NET DBアプリの基本的なモデル。VB 2005を使ってデータセットを定義。
【コラム】 データセットとデータテーブルの実体
プロジェクトに新しい項目として[データセット]を追加すると、プロジェクトに.xsdファイルが追加されるため、本稿ではこれを「データセット」と呼んでいますが、データセットの実体はクラスの定義です。
ソリューション・エクスプローラでプロジェクトに含まれているすべてのファイルを表示させると、.xsdファイルが実際にはいくつかのファイルで構成されていることが分かります。その中の1つに、データセット・デザイナにより自動生成されたVBのソース・ファイルが含まれています。
このソース・ファイルにデータセットやデータテーブルのクラスが記述されています。少し長いコードですが、クラスの骨格部分だけを抜き出すと次のようになります(コメントは筆者が追加したものです)。
' データセットのクラス定義
Partial Public Class MyDBDataSet
Inherits System.Data.DataSet
' データセット内のデータテーブルを保持するフィールド
Private tableMyTable As MyTableDataTable
……MyDBDataSetクラスの記述……
' データテーブルのクラス定義(入れ子クラス)
Partial Public Class MyTableDataTable
Inherits System.Data.DataTable
……MyTableDataTableクラスの記述……
End Class
' データテーブル内のレコードを表すデータロウ
' のクラス定義(入れ子クラス)
Partial Public Class MyTableRow
Inherits System.Data.DataRow
' この列が格納されているデータテーブルを示すフィールド
Private tableMyTable As MyTableDataTable
……MyTableRowクラスの記述……
End Class
End Class
クラスの定義の骨格部分のみを抜き出したもの。MyTableDataTableクラスとMyTableRowクラスは、MyDBDataSetクラスとのみ関連しているので、MyDBDataSetクラスの入れ子クラスとして定義されている。
このコードでは、データセット、データテーブル、そして(本文では解説していませんが)データテーブル内のレコードを示す「データロウ(DataRow)」のクラスが定義されているのが分かります。これらのクラスはそれぞれ、クラス・ライブラリのSystem.Data名前空間に含まれているDataSetクラス、DataTableクラス、DataRowクラスの派生クラスとなっています。
データセットに関していうと、クラス・ライブラリのDataSetクラスでは、データセットの基本的な仕組みが記述されています。そしてその派生クラスであるMyDBDataSetクラスは、データセット・デザイナでのデザインに基づきDataSetクラスをカスタマイズしたクラスとなっています。
実際、既存のDataSetクラスやDataTableクラスだけを使ってもデータベースのレコードを保持することはできますが、自動生成されたそれらの派生クラスを使うとコーディング面で便利になります。例えば、データセット内のデータテーブルにアクセスするには、DataSetクラスでは、
DataSet1.Tables(0)
としてアクセスしなければなりませんが(DataSet1はDataSetクラスのインスタンスとします)、MyDBDataSetクラスでは、
MyDBDataSet1.MyTable
というふうに、MyDBDataSetクラスで追加されているMyTableプロパティが使えます。さらにそのデータテーブルの1行目のレコードのname列の値は、
MyDBDataSet1.MyTable(0).name
として取得できます(nameプロパティは自動生成されたMyTableRowクラスで定義されているプロパティです)。
MyDBDataSetクラスのようなDataSetクラスの派生クラスは「型付きデータセット」(あるいは「型指定されたデータセット」)と呼ばれ、単にこれを「データセット」と呼ぶ場合もあります。
データセットを使った実験
最後に確認の意味も込めて、データセットへのレコードの追加と、グリッド・コントロールとデータセットのデータ連結を試してみましょう。まだ今回はデータベースへのアクセスは行いません。手動でデータセットにレコードを追加してみます。
ここではデータセットにデータテーブルを作成した状態(図5)から始めます。MyTableデータテーブルがMyDBDataSetデータセット内に作成された状態です。
まず、グリッド・コントロールであるDataGridViewコントロールをツールボックスからフォームにドラッグ&ドロップします。
次にフォームをダブルクリックして、以下のようなコードを追加します。
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' データセットのインスタンスを作成
Dim dataset As New MyDBDataSet()
' データセットにレコードを追加
dataset.MyTable.AddMyTableRow( _
1, "名前1", "住所1", New DateTime(2007, 2, 27))
' グリッドとデータテーブルをデータ連結
DataGridView1.DataSource = dataset.MyTable
End Sub
End Class
アプリケーションのロード時にすべての処理を行っている。
ここではデータセットの実体であるMyDBDataSetクラスのインスタンスを作成するコードを最初に記述していますが、この行を記述せずに、ツールボックスに追加されている[MyDBDataSet]という項目*をフォームにドラッグ&ドロップしてもOKです。これを行えば、MyDBDataSetオブジェクトを変数名「MyDBDataSet1」として使えるようになります(これは、Buttonコントロールをフォームにドラッグ&ドロップするとボタンが作成され、「Button1」という変数名でボタンのインスタンスにアクセスできるのと同じですね)。
* この項目がツールボックスで見つからない場合には、一度プロジェクトをビルドしてみてください。
続く行のAddMyTableRowメソッドは、データテーブルの実体であるMyTableDataTableクラス(自動生成されたクラス)で定義されているメソッドです。
最後のデータ連結を行っている部分では、DataGridViewコントロールのDataSourceプロパティにデータテーブルを直接指定していますが、DataSourceプロパティにデータセットを指定して、DataMemberプロパティでデータテーブル名である「MyTable」を指定しても構いません。
さて、プログラムを実行すると、次のような画面となるはずです。
データセットに追加したレコードが正しくDataGridViewコントロールに表示されました。
ここで例えば、AddMyTableRowメソッドのパラメータに指定している「"名前1"」を「Nothing」に変更してプログラムを実行してみると、「列 'name' に Null を使用することはできません。」という例外が発生します。これは前回、MyTableテーブルのname列でNullを許可しないようにしたためです。テーブルの制約もデータテーブルに反映されていることが分かります。
実際にデータセットで以上のようなコーディングをすることはほとんどありませんが、データセットに保持されるレコードやデータ連結についてはお分かりいただけたと思います。
冒頭で述べたとおり、データセット(そしてデータテーブル)はレコードを格納するための入れ物であり、データベースにアクセスする機能は持っていません。実際にデータベースにアクセスする機能はテーブルアダプタとして実装されます。
以前のVisual Studio .NET(.NET Framework 1.x)では、非接続型モデルにおけるデータベース・アクセス部分でデータアダプタ(DataAdapterクラス)を使いましたが、VB 2005(.NET Framework 2.0)になって新しくテーブルアダプタが導入されました。次回はこのテーブルアダプタについて解説します。
Copyright© Digital Advantage Corp. All Rights Reserved.