ADO.NETの中心的機能であるデータセットを丁寧に解説。Webアプリケーションで必要とされるDBアクセスのモデルがデータセットにある。
今回はいよいよADO.NETの中心的な機能である「データセット」について解説していく。前回、前々回で解説してきた.NETデータ・プロバイダによるデータベースのアクセスはシンプルかつ高速なものであったわけだが、いってしまえばSQL文を実行するためだけの非常にプリミティブなものだった。今回解説するデータセットは、それらをベースとしてはるかにリッチなデータベースへのアクセス手段を提供する。
ひと昔前までのクライアント/サーバシステムでは、アプリケーションの実行中は常にデータベースに接続しておくのが一般的であった。最大同時接続数に見合うだけのリソースを用意しておけば、この方式はユーザーにとってもプログラマーにとっても快適なものだった。
しかし、クライアントが専用端末からブラウザになった場合、特にインターネット・ワイドなサービスで不特定多数の顧客を想定した場合、当然ながらこのような接続型のモデルは利用不可能である。必要とされるのは、データが読み込みや変更が必要になったときにだけデータベースへの接続を行い、かつ、その接続回数を減らすためにいったん取得したデータを可能な限り使い回すというモデルである。このようなモデルは、従来の接続型モデルと対比させて、「非接続型」のモデルと呼ばれる。
このモデルは特に新しいものでもない。データベース・サーバの負荷を軽減するために、あるいはデータベース・アクセス時のコストを考慮して、従来からでも取得したテーブルのデータを一時的にメモリ上に残しておいてキャッシュ的な使い方をすることがあった。またあるいは、複数の更新処理を効率よく行うために、テーブルの内容を2次元配列などに読み込んでから各行のデータを更新し、最後にいっきに書き戻すような処理もあり得る。いずれにせよ、データベースから取得したデータを保持できるような汎用的なデータ構造、オブジェクト指向言語でいえばクラス構造があらかじめ用意されていれば便利だ。そして.NET Frameworkでは、ADO.NETの一部としてそのようなクラス構造が標準で用意された。これが「データセット」である。
いま述べたように、データセットはデータベースから取得したデータをメモリ上に保持するためのクラス構造、つまり関連したいくつかクラスの集まりである。データセットはさまざまなテーブルから取得された、さまざまなデータを保持するために柔軟な構造になっていなければならない。
以下の図は、データセットを構成するクラスの中でも代表的なものを取り上げ、その包含関係を図示したものだ。
この図で示している4つのクラスは、いずれもSystem.Data名前空間に属している。詳細は後述するが、ここで簡単にそれぞれのクラスについて見ていこう。
■DataColumnクラス
まず、データベースに含まれるテーブルは、通常複数の「列」を持っている。列には名前が付けられていて、その列に入るデータが文字列なのか数値なのかといったデータ型も設定されている。こういった列に関する情報はDataColumnクラスで表される。
■DataRowクラス
テーブルに格納されている具体的なデータは「行」として扱われるが、これはDataRowクラスで表される。1つの行(レコード)には、通常それぞれの列に対応する複数のデータを含んでいるが、同様に1つのDataRowオブジェクトにも、列の数だけ実データを格納することができる。
■DataTableクラス
DataTableクラスはデータベース内のテーブルに対応するクラスで、上記2つのクラスの複数のオブジェクトを保持できる。
■DataSetクラス
通常、1つのデータベースには複数のテーブルが存在する。データベースに対応し、DataTableクラスで表された複数のテーブルを保持できるクラスがDataSetクラスである。
「データセット」という呼び名は、DataSetクラスの名前に由来するものだ。データセットの実体は、System.Data名前空間にあるDataSetクラスに関連した一連のクラスであると考えてよいだろう。
上の図には示していないが、データセットにはこれら以外にも、テーブル間(DataTableオブジェクト間)のリレーション(テーブル間の関連情報)を表すDataRelationクラスなども用意されている。データセットには、実際のデータベースをそっくりそのままメモリ上で表現できるほどの数々のクラスが用意されているというわけだ。データセットがあれば、どのようなテーブルのデータでも、テーブルや列の情報も含めてメモリ上に持つことができるのである。
データベースの構造や行データを保持する入れ物としてデータセットが用意された。次に必要となるのは、実際のデータベースにアクセスし、データセットにデータを読み込んだり、データセットの内容をデータベースに書き戻したりする仕組みだ。今回ではまず、前者のデータセットにデータを読み込む場合についてのみ見ていくことにする。
データセットにデータをセットする方法の1つは、DataSetクラスを始めとするデータセットの各クラスのインスタンスを作成し、それらをつなぎ合わせた後、第2回で解説したようにSqlDataReaderクラスなどを使ってDataRowオブジェクトにデータを代入していくというものだ。しかしこうした手順を地道に行わなくても、これらの処理を一括して代行してくれる便利な「データアダプタ」クラスがADO.NETには用意されている。
データアダプタは、その名前が表すようにデータベースとデータセットの間をつなぐ「アダプタ」の役目を果たす。
具体的にはデータアダプタは、データベースに接続し、テーブルからレコードを取得し、データセット内にレコードの値をセットし、接続を閉じる。このときテーブルから列情報なども取得しデータセットを構成する一連のクラスのインスタンス化もデータアダプタが行う。
このような処理内容からも分かるように、データアダプタは第2回で解説した.NETデータ・プロバイダに含まれるクラスである。そのため、使用するデータベース製品の種類ごとに対応するデータアダプタのクラスが用意されている。
本連載で対象としているMSDE(あるいはSQL Server)用の.NETデータ・プロバイダでは、System.Data.SqlClient名前空間にあるSqlDataAdapterクラスがデータアダプタを表すクラスである。本連載ではここまでに、次のようなSQL Server用の.NETデータ・プロバイダのクラスを見てきた。
今回用いるSqlDataAdapterクラスで主要な.NETデータ・プロバイダのクラスが出揃ったことになる。
一方、データセットは.NETデータ・プロバイダのクラスではないという点にも注意してほしい。データセットは、データアダプタにより取得されたレコードを格納するための単なる入れ物である。データセットにはデータベースにアクセスする機能は備わっていない。
Copyright© Digital Advantage Corp. All Rights Reserved.