レッスン 1 はじめての ADO.NET

学習内容 ■ ADO.NET を構成する主なオブジェクトとそれらのしくみを学習する
■ データアダプタ構成ウィザードを使用して、Connection オブジェクトと DataAdapter オブジェクトを生成する
■ DataSet オブジェクトを自動的に生成する
■ コントロールのプロパティを DataSet オブジェクトにバインドする
■ 実行時にデータを DataSet オブジェクトに挿入する

ADO.NET は、.NET Framework の他のコンポーネントと同様に、オブジェクト間のやり取りを通じて必要な機能を提供する、一連のオブジェクトで構成されています。オブジェクトモデルを使用するには、すべてを理解しなければならないように見えるため、暗い気持ちになるかもしれません。

まず第一歩を踏み出しましょう。そのためには、基本的な概念を理解することから始めましょう。特定のオブジェクトの機能について学習する前に、各オブジェクトの機能とそれらの相互作用を全体的に理解する必要があります。

これが、このレッスンの目的です。このレッスンでは、ADO.NET の主なオブジェクトと、これらのオブジェクトが物理的なデータストアからデータを取り出すためのしくみについて見ていきます。一例として、いくつかのオブジェクトを構築し、それらをバインドして、簡単なデータフォームを作成してみます。

■ 1.1 基本的な相互接続

このレッスンでは、ADO.NET のオブジェクトモデルの各オブジェクトを理論的な面から見ていきます。実際、これらのオブジェクトは互いに深く結び付いているため、オブジェクトを単体でとらえることは不可能です。

まだ説明していないメソッドやプロパティが必要になった場合は、それらの説明が記載されているレッスンを「参照」に示します。

参照 ここでは、まだ説明していないプロパティやメソッドが説明されている場所を示します。

■ 1.2 ADO.NET のオブジェクトモデル

次の図は、ADO.NET のオブジェクトモデルの主なオブジェクトの関係を示しています。実際のクラスライブラリはもう少し複雑ですが、それらについてはこれ以降のレッスンで取り上げます。ここでは、主なオブジェクトの種類と、それらの一般的な相互作用のしくみを理解してください。

ADO.NET のクラスは、2 つのコンポーネントに分類されます。1 つは「データプロバイダ」と呼ばれるもので (マネージプロバイダとも呼ばれます) 、物理的なデータストアとの通信を処理します。もう 1 つは「データセット」と呼ばれるもので、実際のデータを表します。どちらのコンポーネントも Web フォームや Windows フォームなどのデータコンシューマと通信できます。

1.2.1 データプロバイダ

データプロバイダコンポーネントは、データソースに固有のものです。.NET Framework には、OLE DB データソースと通信できる汎用プロバイダと、SQL Server 7.0 以上に最適化された SQL Server プロバイダという、2 種類のデータプロバイダが含まれています。Oracle や DB2 など、他のデータベース用のデータプロバイダも、今後リリースされる予定です。また、独自のデータプロバイダを作成することも可能です (これは本書では取り上げません) 。

.NET Framework の 2 つのデータプロバイダは同じオブジェクトで構成されていますが、オブジェクトの名前や、一部のプロパティとメソッドが異なっています。具体的には、SQL Server データプロバイダのオブジェクトは「Sql」という名前で始まりますが (SqlConnection など) 、OLE DB データプロバイダのオブジェクトは「OleDb」という名前で始まります (OleDbConnection など) 。

Connection オブジェクトは、データソースへの物理的な接続を表します。Connection オブジェクトのプロパティは、データプロバイダ (OLE DB データプロバイダの場合) 、接続先のデータソースとデータベース、接続時に使用する文字列を決定します。Connection オブジェクトのメソッドは、接続を開く、接続を閉じる、データベースを変更する、トランザクションを管理するという単純なもので構成されています。

Command オブジェクトは、データソースで実行する SQL ステートメントまたはストアドプロシージャを表します。Command オブジェクトは、それぞれ個別に作成して、Connection オブジェクトで実行できます。Command オブジェクトは、DataAdapter オブジェクトによって、DataSet オブジェクトとデータソースとの通信を処理するために使用されます。Command オブジェクトは、1 つの値を返す、1 つ以上の行を返す、または値をいっさい返さない SQL ステートメントやストアドプロシージャをサポートします。

DataReader オブジェクトは、データソースから順方向の読み取り専用のデータストリームを取得するための、高速でオーバーヘッドの少ないオブジェクトです。DataReader オブジェクトは、コードから直接生成することはできません。DataReader オブジェクトを生成するには、Command オブジェクトの ExecuteReader メソッドを呼び出さなければなりません。

DataAdapter オブジェクトは、データプロバイダのオブジェクトとしては、最も複雑な機能を持つオブジェクトで、Connection オブジェクトと DataSet オブジェクトを仲介する役目を果たします。DataAdapter オブジェクトには、SelectCommand、UpdateCommand、InsertCommand、DeleteCommand の 4 つの Command オブジェクトが含まれています。DataAdapter オブジェクトは、SelectCommand オブジェクトを使用して DataSet オブジェクトを生成します。他の 3 つのオブジェクトは、必要に応じてデータセットに変更されたデータを戻すために使用します。

ADO (ActiveX Data Objects)

Connection および Command オブジェクトは、機能的には ADO の Connection および Command オブジェクトに相当します (主な違いは、サーバーカーソルをサポートしないことです。サーバーカーソルとは、サーバー側で実装されるカーソルのことです) 。DataReader オブジェクトの機能は、ファイアホース (firehose) カーソルに似ています。ADO には、DataAdapter オブジェクトと DataSet オブジェクトに相当するオブジェクトはありません。

1.2.2 データセット

データセットは、メモリ上でのデータを表します。次の図は、データセットの構造を示しています。データセットは、テーブルおよびテーブル間のリレーションシップで構成される、単純なリレーショナルデータベースと考えることができます。ただし、データセットがデータソースに常時接続していないことに注意しなければなりません。データセットはデータソースを認識せず、実際には複数のデータソースのデータで構成できます。

データセットは、DataTableCollection と DataRelationCollection という主に 2 つのオブジェクトで構成されています。DataTableCollection オブジェクトは、0 個以上の DataTable オブジェクトで構成されます。DataTable オブジェクトは、Columns、Rows、Constraints の 3 つのコレクションで構成されます。DataRelationCollection は、0 個以上の DataRelation オブジェクトで構成されます。

DataTable オブジェクトの Columns コレクションは、DataTable オブジェクトを構成する列 (DataColumn オブジェクト) を定義します。DataColumn オブジェクトには、ColumnName プロパティと DataType プロパティの他に、null 値を許可するかどうか (AllowDBNull) 、最大の長さ (MaxLength) 、列の値を計算するための式 (Expression) を定義するプロパティがあります。

DataTable オブジェクトの Rows コレクションは、Columns コレクションによって定義される実際のデータ (Row オブジェクト) を保持します。Row コレクションは空の場合があります。DataTable オブジェクトでは、これらの Row オブジェクトごとに、元の値、現在の値、新しい (変更される) 値が保持されます。後述するように、この機能は特定のタスクに効果的です。

ヒント ADO.NET の DataTable オブジェクトは、基本的には ADO の Recordset オブジェクトと同じ機能を提供しますが、オブジェクトモデルでの役割は大きく異なっています。

DataTable オブジェクトの Constraints コレクションは、0 個以上の Constraint オブジェクトで構成されます。リレーショナルデータベースと同様に、Constraint オブジェクト (制約) はデータの整合性を維持するために使用されます。ADO.NET では、2 種類の制約がサポートされています。1 つは ForeignKeyConstraint で、リレーショナル整合を維持します。もう 1 つは UniqueConstraint で、データ整合を維持します (テーブルに重複する行を追加できないようにする制約です) 。また、DataTable オブジェクトの PrimaryKey プロパティは、エンティティの整合性を保証します (それぞれの行が一意になるようにします) 。

最後に、DataSet オブジェクトの DataRelationCollection プロパティは、0 個以上の DataRelation オブジェクトで構成されます。DataRelation オブジェクトは、あるテーブルのマスタ行から別のテーブルの関連する行をたどるための、簡単なプログラミングインターフェイスを提供します。たとえば、Order 列が指定された場合は、DataRelation オブジェクトを使用して、関連する OrderDetail 行を簡単に取り出すことができます (DataRelation オブジェクト自体は、リレーショナル整合を保証しない点に注意してください。制約はこのために使用されます) 。

■ 1.3 データと Windows フォームのバインディング

データをフォームに接続するプロセスを、「データバインディング」といいます。データバインディングはコードを記述して実行しますが、Visual Studio .NET のデザイナを使用すると、より簡単に処理できます。このレッスンでは、デザイナとウィザードを使用して、Windows フォームにデータをすばやくバインドする方法について説明します。

重要 本書の実習ファイルをまだインストールしていない場合は、「はじめに」の「サンプルファイルのインストールと使用」の内容に従って、実習ファイルをインストールしてください。
参照 Connection オブジェクトについては「レッスン 2 接続の作成」を参照してください。DataAdapter オブジェクトについては「レッスン 4 データアダプタ」を参照してください。

1.3.1 フォームに Connection オブジェクトと DataAdapter オブジェクトを追加する

データをバインドするための最初の作業は、データプロバイダオブジェクトを生成することです。Visual Studio .NET には、これを簡単に行うデータアダプタ構成ウィザードが用意されています。DataAdapter オブジェクトが追加された後は、[データアダプタプレビュー] ウィンドウを使用して、構成が正しいかどうかを確認できます。

重要 このレッスンの実習を行うには、SQL Server 2000 または SQL Server 2000 Desktop Engine に収録されている Northwind データベースが必要です。Visual Studio .NET の Enterprise Edition を使用している場合は、[C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\Setup\msde\setup] フォルダの sql2000.msi をインストールすると、SQL Server 2000 Desktop Engine をセットアップできます (このフォルダは、Visual Studio .NET のインストール時に作成されます) 。SQL Server サービスを開始するには、コンピュータを再起動する必要があります。

Northwind データベースを作成するには、[コマンドプロンプト] ウィンドウを開いて、カレントディレクトリを [C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\Setup] フォルダへ移動し、次のコマンドを入力します。

osql -E -iinstnwnd.sql

これにより、instnwd.sql スクリプトが実行されます。スクリプトの実行が終了したら、[コマンドプロンプト] ウィンドウを閉じてください。

Windows フォームに Connection オブジェクトを追加する

 
  1. Visual Studio .NET を起動して、[C:\ADO.NET 実践講座 \ レッスン 1\ < VB または C# > \EmployeesForm] フォルダの EmployeesForm プロジェクトを開く。
  2. [ソリューションエクスプローラ] ウィンドウで [Employees.vb] (C# の場合は、[Employees.cs] ) をダブルクリックする。

    [デザイナビュー] ウィンドウに Employees フォームが表示されます。

  1. [ツールボックス] ウィンドウで、[データ] タブの [SqlDataAdapter] コントロールをフォーム上へドラッグする ( [ツールボックス] ウィンドウが表示されていない場合は、ツールバーの [ツールボックス] ボタンをクリックする) 。

    データアダプタ構成ウィザードが起動します。

  2. [次へ] をクリックする。

    [データ接続の選択] ページが表示されます。

  3. [新しい接続] をクリックする。

    [データリンクプロパティ] ダイアログボックスが表示されます。

  4. サーバー名とログオンに必要な情報を入力し、Northwind データベースを選択して、[接続のテスト] をクリックする。

    [Microsoft データリンク] メッセージボックスに接続が成功したことを示すメッセージが表示されます。

    ヒント 手順 6 を完了するための情報は、システム管理者に問い合わせてください。


  5. [OK] をクリックして、メッセージボックスを閉じる。もう一度 [OK] をクリックして、[データリンクプロパティ] ダイアログボックスを閉じる。[次へ] をクリックする。

    [クエリの種類の選択] ページが表示されます。

  6. [SQL ステートメントの使用] が選択されていることを確認し、[次へ] をクリックする。

    [SQL ステートメントの生成] ページが表示されます。

  7. [クエリビルダ] をクリックする。

    [クエリビルダ] ダイアログボックスが表示された後、[テーブルの追加] ダイアログボックスが表示されます。

  8. Employees テーブルを選択して [追加] をクリックし、[閉じる] をクリックする。

    [クエリビルダ] ダイアログボックスに Employees テーブルが追加されます。

  9. Employees ビューに表示されているフィールド名の横のチェックボックスをオンにし、クエリに EmployeeID、LastName、FirstName、Title、HireDate、Notes フィールドを追加する。

    3 番目のウィンドウ領域に作成された SQL コマンドが表示されます。

  10. [OK] をクリックして、[クエリビルダ] ダイアログボックスを閉じ、[次へ] をクリックする。

    フォームに Connection オブジェクトと SqlDataAdapter オブジェクトが追加されたことを示す、[ウィザードの結果の表示] ページが表示されます。

  11. [完了] をクリックして、データアダプタ構成ウィザードを終了する。

    SQLDataAdapter オブジェクトと SQLConnection オブジェクトが作成され、フォームの下部にあるコンポーネントトレイに表示されます。

1.3.2 DataSet オブジェクトの生成

データストアとの物理的な通信は、Connection オブジェクトと DataAdapter オブジェクトによって処理されますが、フォームにバインドするデータをメモリ上に読み込む作業が残っています。コントロールは、配列やコレクションを含め、ほぼすべての構造にバインドできますが、通常は DataSet オブジェクトを使用します。

データプロバイダオブジェクトと同様に、Visual Studio .NET にはこのプロセスを自動化する機能が用意されています。実際にはメニューを選択するだけですが、生成されたコードが表示されるため、Visual Studio .NET が提供する DataSet オブジェクトの基本的な機能をさらに制御できます。

参照 DataSet オブジェクトについては、「レッスン 6 データセット」を参照してください。

DataSet オブジェクトを生成する

  1. [データ] - [データセットの生成] をクリックする。

    [データセットの生成] ダイアログボックスが表示されます。

  2. [新規作成] が選択されていることを確認し、横のボックスにdsEmployeesと入力する。

  3. [OK] をクリックする。

    DataSet オブジェクトが作成され、フォームのコンポーネントトレイに表示されます。

1.3.3 コントロールと DataSet オブジェクトのバインディング

.NET Framework では、「単純」および「複雑」という 2 種類のバインディングがサポートされています。「単純なバインディング」は、日付などの 1 つのデータ要素をコントロールにバインドするときに使用します。「複雑なバインディング」は、リストボックスを複数の注文番号で構成される DataSet オブジェクトにバインドするなど、コントロールを複数のデータ要素にバインドするときに使用します。

単純なバインディングは、コントロールのほとんどのプロパティでサポートされますが、複雑なバインディングは、Windows フォームと Web フォームの一部のコントロール (DataGrid コントロールや ListBox コントロールなど) だけでサポートされています。

参照 単純なバインディングと複雑なバインディングの詳細については、「レッスン 10 Windows フォームでのデータバインディング」および「レッスン 11 Windows フォームでの ADO.NET の使用」を参照してください。

コントロールの Text プロパティを DataSet オブジェクトにバインドする

  1. フォーム上の txtLastname テキストボックス (「姓」と表示されているコントロール) をクリックする。

  2. [プロパティ] ウィンドウで [(DataBindings)] プロパティを展開する。

  3. Text プロパティをクリックし、横の下向き矢印をクリックする。

    利用可能なデータソースの一覧が表示されます。

  4. DsEmployees1 データソースを展開し、Employees データテーブルを展開する。

  5. [LastName] をクリックする。

  6. 次の表に従って、手順 1 ~ 5 を繰り返し、他の TextBox コントロールの Text プロパティを Employees テーブルの列にバインドする。

    コントロール Employees テーブルの列
    lblEmployeeID (ID) EmployeeID
    txtLastname (姓) LastName
    txtFirstname (名) FirstName
    txtHireDate (入社日) HireDate
    txtPosition (役職) Title
    txtNotes (備考) Notes

1.3.4 DataSet オブジェクトへのデータのロード

これで、データソースのデータを操作するためのすべてのコンポーネントが作成されました。最後の作業は、DataSet オブジェクトにデータをロードすることです。

Microsoft Access などの環境では、フォームにデータが自動的にバインドされますが、ここではバインディングを手動で行う必要があります。ただし、ADO.NET のアーキテクチャは、データベースへの固定接続を確立せずに操作できるように設計されています。したがって、接続されていない環境では、プログラムで接続を管理する必要があります。

DataSet オブジェクトにデータをロードするには、DataAdapter オブジェクトの Fill メソッドを使用します。DataAdapter オブジェクトには、Fill メソッドのオーバーロードがいくつか定義されています。最も単純なオーバーロードメソッドには、パラメータとして DataSet オブジェクトの名前を渡します。次の実習では、このオーバーロードメソッドを使用します。

参照 Fill メソッドについては、「レッスン 4 データアダプタ」を参照ください。

DataSet オブジェクトにデータをロードする

Visual Basic

  1. [F7] を押す。

    [コード] ウィンドウに Employees.vb ソースファイルが表示されます。

  2. 「Windows フォームデザイナで生成されたコード」というコードブロックを展開する。

    Public Sub New メソッドが表示されます。

  3. InitializeComponent プロシージャの呼び出しの後に、次のコードを追加する。

    SqlDataAdapter1.Fill(DsEmployees1)
    

    このコードは、DataAdapter オブジェクトの Fill メソッドを呼び出し、パラメータとしてデータを設定する DataSet オブジェクトの名前を渡しています。

  4. [F5] を押す。

    プログラムがビルドされた後、実行されます。
    フォームに 1 行目の情報が表示されます。

    参照 DataAdapter クラスの Fill メソッドについては、「レッスン 4 データアダプタ」を参照してください。

  5. 閉じるボタンをクリックして、フォームを閉じる。

    Visual Studio .NET 環境に制御が戻ります。データのバインディングがそれほど難しくないことがわかります。

C#

  1. [F7] を押す。

    [コード] ウィンドウに Employees.cs ソースファイルが表示されます。

  2. mployees クラスのコンストラクタの最後に、次のコードを追加する。

    sqlDataAdapter1.Fill(dsEmployees1);
    

    このコードは、DataAdapter オブジェクトの Fill メソッドを呼び出し、パラメータとしてデータを設定する DataSet オブジェクトの名前を渡しています。

    参照 DataAdapter クラスの Fill メソッドについては、「レッスン 4 データアダプタ」を参照してください。
  3. [F5] を押す。

    プログラムがビルドされた後、実行されます。
    フォームに 1 行目の情報が表示されます。

  4. 閉じるボタンをクリックして、フォームを閉じる。

    Visual Studio .NET 環境に制御が戻ります。データのバインディングがそれほど難しくないことがわかります。

■ まとめ

目的 操作
データアダプタ構成ウィザードを使用した Connection オブジェクトと DataAdapter オブジェクトの追加 フォーム上に DataAdapter オブジェクトをドラッグし、ウィザードの指示に従って設定を行う。
型指定された DataSet オブジェクトの自動的な生成 [データ] - [データセットの生成] をクリックする。[データセットの生成] ダイアログボックスの項目を適切に設定し、[OK] をクリックする。
コントロールのプロパティとデータソースの単純なバインディング [プロパティ] ウィンドウの (DataBindings) プロパティで、データソース、データテーブル、列を選択する。
DataSet オブジェクトへのデータのロード DataAdapter クラスの Fill メソッドを使用する。

myDataAdapter.Fill(myDataSet)