データセットとデータテーブル データセット (DataSet) とは何かに付いて 簡単に説明する データセットとは 典型的な.NET の Windows データベースアプリケーションでは データセットを通じてアプリケーションからデータベースにアクセスする データセットとは 簡単に謂うと データベースから取得したレコードをメモリ上に持つ為の入れ物で有る 例えば データベースからレコードを取得し 其れをグリッドコントロールに表示する様な Windows アプリケーションの大まかな構造は 次の図の様に成る 此の構造では 先ず グリッドでの表示に必要なレコードをデータベースからデータセットに取得する 此れは データベースに SELECT 文を発行する事に依り行われる SELECT 文の実行に依り得られたレコードは データセット内に総て格納される グリッドコントロールとデータセットは 予め データ連結 ( データバインド ) して置く 此れに依りデータセットの内容は グリッドコントロールにリアルタイムに反映される 其の結果 今取得したデータセット内のレコードがグリッドに表示される訳で有る グリッドコントロール上ではデータセットの内容に対して 並べ替えやページングが行える グリッド上でデータを追加 編集 削除した場合には データ連結に依りデータセットの内容も変化する 変更が加えられたデータセットは ( 通常は ) ユーザーからの指示のタイミングでデータベースに反映される 此の場合にはデータセットの変更内容に従って INSERT UPDATE DELETE 文がデータベースに対して発行される 以上は Windows アプリケーションに於けるデータベースアクセスのモデルと謂って良い 詰まり 最初にデータセットにレコードを取得し ユーザーに依る操作が完了した後 データセットのレコードをデータベースに反映すると謂うモデルで有る 此のモデルでは 最初と ( レコードの更新が有る場合には ) 最後にしかデータベースにアクセスせず 基本的にはデータベースとは非接続で有る為 非接続型データアクセスと呼ばれる Visual Basic 2010 や Visual Studio 2010 の IDE( 統合開発環境 ) を使って構築する Windows データベースアプリケーションは基本的に此のモデルと成る -1-
データセット内のテーブルを表すデータテーブル Visual Basic 2010 の IDE でデータセットを使用する前に データテーブル (DataTable) に付いても解説して置く データベースにテーブルが含まれて居る様に データセットにはデータテーブルが含まれる 然して データベースのレコードが実際にはテーブル内に格納されて居る様に データベースから取得したレコードは 実際にはデータセット内のデータテーブルに格納される 下図に データセットと実際のデータベースの対比を示す データテーブルでは データベースのテーブルと同様のスキーマを定義する事が出来る 詰まり データテーブルには列を定義出来 各列は列名やデータ型 制約等を設定出来る 勿論 主キーと成る列も設定出来る 此の様に データテーブルは 実際のテーブルと同じ構造を持つ事が出来 データベースから取得したレコードを 其の儘 格納出来る様に成って居る 亦 SQL Server 等のリレーショナルデータベースでは テーブル間のリレーション ( リレーションシップ 関連 ) が重要だが データセットではデータテーブル間のリレーションも表現出来 データベースでの実際のリレーションをデータセット内でも維持出来る様に成って居る Visual Basic 2010 でプロジェクトにデータセットを追加 其れでは Visual Basic 2010 でデータセットを使用して観る事にする プロジェクトに SQL データベースを新規追加すると DB ファイルで有る MDF ファイルをプロジェクトに追加した後 [ データソース構成ウィザード ] が起動し 此れに依り XSD ファイルが自動的に追加される ( 例えば DB ファイルの名前を MyDB.mdf と仕た場合には XSD ファイルのファイル名は MyDBDataSet.xsd と成る ) 此の XSD ファイルがデータセット ( 正確にはデータセットの定義 ) で有る 併し [ データソース構成ウィザード ] が起動した時に [ キャンセル ] ボタンをクリックすると 当然の事乍 XSD ファイルはプロジェクトに追加されない 此の様に XSD ファイルがプロジェクト内に含まれて居ない場合には プロジェクトに新しい項目と仕て [ データセット ] を追加する事に依り XSD ファイルをプロジェクトに追加する事が出来る 此処では 此の手順に付いて解説する -2-
[ プロジェクト ] メニューから [ 新しい項目の追加 ] をクリックし [ 新しい項目の追加 ] ダイアログで データセットを選択して [ 追加 ] ボタンをクリックする 此の場合 既定の名前は DataSet1.xsd なので 必要に応じて 変更する必要が有る データセットを追加すると エディタ中央に データセットデザイナが表示される ( ソリューションエクスプローラでデータセットをダブルクリックすると 何時での表示する事が出来る ) 此れはデータセットの内容を編集する為の物で有る -3-
データセット内にデータテーブルを作成 データセットデザイナには データベースエクスプローラからテーブルをドラッグ & ドロップしたり ツールボックスからデータテーブル等のコンポーネントをドラッグ & ドロップ出来る 実際のテーブルと同じ構造を持つデータテーブルを簡単に作成するには データベースエクスプローラからテーブルをデータセットデザイナ上にドラッグ & ドロップする 此れに依りデータベースからテーブルのスキーマ情報が取得され データセット内にデータテーブルが作成される 此処で作成するデータテーブルは 実際のテーブルの構造と全く同じで有る必要は無く データテーブルに独自に列を追加したり プログラムで参照しない様な不要な列を削除したり出来る データベースに複数のテーブルが有る場合には 上図の様に複数のデータテーブルを作成する事が出来る 亦 テーブル間にリレーションが設定されて居る場合には データテーブル間にも自動的にリレーションが設定される様に成って居る 猶 上図では データテーブルで有る authors の下に authorstableadapter titleauthor の下に titleauthortableadapter と謂うボックスが付いて居るが テーブルアダプタ (TableAdapter) で有る 此のテーブルアダプタがテーブルからレコードを取得して 其れをデータテーブルに格納をする役目を果たす データセットとデータテーブルの実体 プロジェクトに新しい項目と仕てデータセットを追加すると プロジェクトに XSD ファイルが追加される為 便宜上 此れをデータセットと呼んで居るが データセットの実体はクラスの定義で有る ソリューションエクスプローラでプロジェクトに含まれて居る総てのファイルを表示させると XSD ファイルが実際には幾つかのファイルで構成されて居る事が解る 其の中に データセットデザイナに依り自動生成された Visual Basic のソースファイル (xxxdataset.designer.vb) が含まれて居る 此のファイルのコードでは データセット データテーブル 然して データテーブル内のレコードを示すデータロウ (DataRow) のクラスが定義されて居る 此等のクラスは夫々れ クラスライブラリの System.Data 名前空間に含まれて居る DataSet クラス DataTable クラス DataRow クラスの派生クラスと成って居る MyTableDataTable クラスと MyTableRow クラスは MyDBDataSet クラスと而巳関連して居るので MyDBDataSet クラスの入れ子クラスと仕て定義されて居る -4-
データセットに関して謂うと クラスライブラリの DataSet クラスでは データセットの基本的な仕組みが記述されて居る 然して 其の派生クラスで有る MyDBDataSet クラスは データセットデザイナでのデザインに基づき DataSet クラスをカスタマイズしたクラスと成って居る 実際 既存の DataSet クラスや DataTable クラス丈を使ってもデータベースのレコードを保持する事は出来るが 自動生成された其等の派生クラスを使うとコーディング面で便利に成る 例えば データセット内のデータテーブルにアクセスするには DataSet クラスでは DataSet1.Tables(0) と仕てアクセスしなければ成らないが (DataSet1 は DataSet クラスのインスタンスとする ) MyDBDataSet クラスでは MyDBDataSet1.MyTable と謂う風に MyDBDataSet クラスで追加されて居る MyTable プロパティが使える 更に 其のデータテーブルの 1 行目のレコードの name 列の値は 下記の様に仕て取得出来る (name プロパティは自動生成された MyTableRow クラスで定義されて居るプロパティで有る ) MyDBDataSet1.MyTable(0).name MyDBDataSet クラスの様な DataSet クラスの派生クラスは 型付きデータセット ( 又は 型指定されたデータセット ) と呼ばれ 単に此れをデータセットと呼ぶ場合も有る -5-
テーブルアダプタの基礎 此処では データベースとデータセットの橋渡し役と成るテーブルアダプタ (TableAdapter) に付いて解説する 此のテーブルアダプタは.NET Framework 1.x の頃には無かった Visual Studio 2005 以降の新しい機能で アプリケーションのデータベースアクセスに関わる処理を簡潔に纏める事が出来る テーブルアダプタとは テーブルアダプタは データベースのテーブルからレコードを取得し 取得したレコードをデータセット内のデータテーブルに格納する機能を持ったコンポーネントで有る 実際には下図の様に テーブルアダプタがデータベースに対して SELECT 文を発行し 其の結果 ( 通常は複数のレコード ) をデータテーブルに挿入する 典型的な.NET の Windows データベースアプリケーションでは 最初に一度丈此の様なデータベース処理を行い 其れ以降はデータベースとは切り離された状態で ( データテーブル内のデータに対して ) 業務処理を行う テーブルアダプタは亦 ユーザーの操作に依り追加 編集 削除されたデータテーブルの内容をデータベースのテーブルに反映する為に INSERT UPDATE DELETE 文等も発行する 亦 更に 例えば レコードの件数を知り度い場合には テーブルアダプタに其の様な SELECT 文を発行する機能を独自に追加して 其れを呼び出す事が出来る 此の様に Windows データベースアプリケーションでは データベースに関する処理を総てテーブルアダプタの機能と仕て実装し 其れをビジネスロジックから呼び出すと謂うのが基本的なパターンで有る データテーブルの実体 テーブルアダプタの実体は 自動生成されたクラスで有る 其のクラス名はテーブルアダプタの名前と同じに成る 此のクラスは 前回で見たデータセットのクラスと同じ データセットのコードビハインドファイル (< データセット名 >.Designer.vb) に記述される 亦 Fill,GetData クエリと謂うのは 自動生成されたクラスで定義されて居る Fill メソッドと GetData メソッドを 1 つのクエリと仕て纏めて表した物で有る 其のソースコードでメソッドの定義を観れば解るが 此等 2 個のメソッドは Public なメソッドで有り 次の様なパラメータや戻り値を持つ Function Fill(ByVal datatable As MyDBDataSet.MyTableDataTable) As Integer Function GetData( ) As MyDBDataSet.MyTableDataTable 既に述べた様に 此等のメソッドは孰れも 其のメソッド内で SELECT 文を発行してレコードを取得し 其れをデータテーブルに詰めて返す物だが 此の 2 個は其の返し方が異なる -6-
先ず Fill メソッドは パラメータと仕てデータテーブルのオブジェクトを受け取り 其のデータテーブルに対して 取得した結果を格納する 戻り値は取得したレコード件数と成る 一方 GetData メソッドはメソッド内部でデータテーブルのオブジェクトを作成し 其処に SELECT 文の結果を格納して 其のオブジェクトを返す パラメータの型が MyDBDataSet.MyTableDataTable と成って居るのは MyTableDataTable クラスが データセットの実体で有る MyDBDataSet クラスの入れ子クラスだからで有る 実際に使用するか何うかに拘らず 通常 テーブルアダプタには 此の 2 個の形式のメソッドがセットで作成される データセットデザイナは 此等の 2 個のメソッドを Fill,GetData( ) の様にセットにして表示する アプリケーションアーキテクチャに於けるテーブルアダプタの位置付け 業務アプリケーションを設計する際には アプリケーション構造の見通しを良くし 保守性を高める為に アプリケーション構造を階層化し 各処理をコンポーネントに分割して設計する事が推奨される 所謂 アプリケーションアーキテクチャと呼ばれる物で有る データセットとテーブルアダプタに依るデータベースアクセスは.NET で推奨されて居るアプリケーションアーキテクチャに従って居ると謂える 下図は.NET で推奨されて居る論理アーキテクチャモデルとの対応付けで有る データセット ( データテーブル ) は 業務データのコンテナで有るビジネスエンティティコンポーネントに該当する 亦 データベースへのアクセスを纏めたテーブルアダプタは データアクセスロジックコンポーネントに該当する -7-
先ず 此処でポイントと成るのは アプリケーション内で実際にデータベースにアクセスする処理を総てテーブルアダプタと仕て実装し 出来る限り纏めて置くと謂う点で有る 業務処理 ( ビジネスロジック ) 内で直接データベースにアクセスしたり ( 酷い場合には ) ボタンのイベントハンドラでデータベースにアクセスしたりと謂う事を仕無い様にする 亦 テーブルアダプタに依り取得されたデータは データテーブル 或いは データセットと仕て 各階層間で受け渡しを行う ビジネスエンティティコンポーネントは 単成るデータの入れ物で ビジネスロジックを持たせないと謂う点もポイントと成る 勿論 上図の論理アーキテクチャは 主に大規模な分散アプリケーションの構築を想定して居るので 必ずしも此処で対象と仕て居る様な業務アプリケーションには完全には一致しないかも知れない 併しアプリケーションアーキテクチャと謂う物は 成功事例に基づいて作成されたパターンで有るから 頭の片隅にでも入れて置けば 何う遣って実装しようかと迷った時の参考に成ると思う -8-
Visual Studio 2010 でデータベースの更新が反映されない場合 Visual Studio 2010 と SQL Server 2012 Express Edition( 既定では Visual Studio 2010 と同時にインストールされる ) を組み合わせてデータベースアプリケーションを作成する場合には データベースファイル ( 以下 DB ファイル ) のアタッチ機能に依り 従来よりも手軽に開発用のデータベースを取り扱う事が出来る 但し 此の機能を利用して開発を行って居ると アプリケーションで更新した筈のデータがデータベースに全く反映されて居ない ( 様に観える ) と謂う状況が発生する事が有る データベースファイルのアタッチ機能 DB ファイルのアタッチ機能とは 簡単に謂えば データベースが格納されて居るファイル ( 実際には MDF ファイルと LDF ファイルのペア ) を Access の MDB ファイルの様に Visual Studio 2010 やアプリケーションから直接開く事が出来る機能だ 通常此等のファイルは SQL Server のサービスに依り管理されて居る為 ファイルを操作する為にはサービスを停止しなくては成らない 此の機能に依り テスト用に構築したデータベースのコピーに対して更新処理等をテストすると謂う事が可能に成る 詰まり テストを実施する度に DB ファイルのコピーを使用すれば 元の DB ファイルを更新する事無く 常に同じテスト用データでテストが出来ると謂う訳で有る DB ファイルの [ 出力ディレクトリにコピー ] プロパティ Visual Studio 2010 で新しいデータソースの追加等を行う際に [ 新しい接続 ] のデータソースと仕て Microsoft SQL Server データベースファイルを選択し 新規や既存の DB ファイルを選択すれば プロジェクト内に DB ファイルを作成する事が出来る 以下の画面は プロジェクトに追加した DB ファイル (MyDD.mdf) をソリューションエクスプローラで選択し 其のプロパティを表示して居る処で有る -9-
此処で [ 出力ディレクトリにコピー ] プロパティに注目して欲しい 此の出力ディレクトリとは 実行ファイルが作成されるディレクトリの事で Windows アプリケーションをデバッグ実行する場合には プロジェクトの有るディレクトリ配下の bin Debug ディレクトリと成る 此のプロパティのデフォルトは [ 常にコピーする ] で有る 詰まり アプリケーションをデバッグ実行した場合には プロジェクト内の DB ファイルが毎回 bin Debug ディレクトリに ( 上書き ) コピーされる事に成る 然して ( デフォルトの設定では ) デバッグ実行されたアプリケーションは 其のコピーされた bin Debug ディレクトリ内の DB ファイルに対してアクセスを行うので有る 此の為 アプリケーションの実行が終わった後に プロジェクト内の DB ファイルの内容を確認しても 当然乍 データベースは更新されて居ない 更新結果を確認し度いなら 此の場合には bin Debug ディレクトリに有る DB ファイルを開く必要が有る 勿論 再度アプリケーションをデバッグ実行すると 其の DB ファイルは上書きされて仕舞う 更新したデータをデータベースに残しつゝ 何度もアプリケーションを実行し度い場合には 此のプロパティを [ コピーしない ] に仕て置けば良い 但し 此の場合には 初回時に手動で DB ファイルを実行ディレクトリにコピーする必要が有る [ 新しい場合はコピーする ] を選択すればデータを残しつゝ 初回の手動コピーも不要だが 此の新しい場合と謂うのは DB ファイルを新規作成した場合と謂う意味ではなく コピー先の DB ファイルよりも元の DB ファイルが新しい場合で有る 詰まり テーブルのスキーマを修正したりする丈でもデータベースが新しく成り 実行時には DB ファイルがコピーされて仕舞う為 注意が必要で有る -10-