Visual Web Developer 2005 Express Edition と SQL Server 2005 Express Edition による Web 開発 (第 2 部)
データ アクセス : SQL Server Express とデータ コンポーネントの調査
Dan Burman
Citigate Hudson
July 2004
日本語版最終更新日 2004 年 12 月 7 日
対象 :
Microsoft ASP.NET
2.0
Microsoft SQL Server 2005 Express Edition テクニカル
プレビュー
Microsoft Visual Basic 2005 Express
Edition
Microsoft Visual Web Developer 2005 Express
Edition
概要 : Visual Web Developer 2005 Express Edition と SQL Server 2005 Express Edition による Web アプリケーションの作成の第 2 部では、データベースの基本、SQL Server Express の機能、データ エクスプローラをセットアップして SQL Server Express データベースを参照する方法、およびデータ ソースの使用について説明します。また、データ コンポーネントを使用して n 層アーキテクチャをビルドする方法についても説明します。
注 この資料は、2004 年 5 月時点の Visual Web Developer 2005 Express Edition のアルファ リリースと SQL Server 2005 Express Edition テクニカル プレビューに基づいています。ここに記載される情報は変更される可能性があります。
関連サンプル コード ExpressWebDevelopment.exe (英語) のダウンロード
目次
はじめに
SQL Server 2005 Express Edition の導入により、ASP.NET 2.0 でのデータ統合が大幅に促進されます。SQL Server Express は、強力なファイル ベースのパーソナル データベースで、SQL Server 2005 コード ベースを基礎としてビルドされています。SQL Server Express の用途として想定されているのは基本的な開発なので、実稼動サーバーに必要なトラフィックは処理されません。SQL Server Express を使用する利点は、SQL Server Express が Visual Web Developer 2005 Express Edition に付属していて、開発環境にシームレスに統合されることです。SQL Server Express の最終リリースまでには、データ オブジェクトを管理する固有の GUI が実装されます。しかし、この資料の執筆中の時点では、このインターフェイスの実装は完了していません。代わりに、この資料では、Visual Web Developer 2005 Express Edition のデータ エクスプローラを使用して SQL Server Express に接続します。
この資料で使用する、いくつかの基本的なデータベースの概念について説明します。
データベースの概念
- テーブル
- 行と列で構成された 2 次元のオブジェクト。リレーショナル
データベースにデータを格納するために使用します。各テーブルには、データベースによってモデル化されたオブジェクトの種類の 1
つに関する情報が格納されています。たとえば、教育のデータベースは、1 番目が教師のテーブル、2 番目が学生のテーブル、3
番目がクラスのテーブルのようになります。
テーブルの列は、モデル化されたオブジェクトの属性 ( 姓、名、住所など) を表します。モデル化されたオブジェクトの 1 つ 1 つがテーブルの各行として表されます。たとえば、クラス テーブルのある行に、午前 9 時に行われる代数 1 の授業に関する情報が記録され、別の行に、午前 10 時に行われる世界史の授業に関する情報が記録されます。
- ビュー
- SQL ステートメントのテーブルと同じ方法でデータベース オブジェクトを参照できます。ビューは SELECT ステートメントを使用して定義され、このステートメントの結果セットを含むオブジェクトと考えられます。
- インデックス
- リレーショナル データベースでは、インデックスは、キー値に基づいてテーブルの行に含まれるデータにすばやくアクセスできるデータベース オブジェクトを示します。また、インデックスにより、テーブルの行が一意に設定されます。SQL Server では、クラスタ化インデックスと非クラスタ化インデックスがサポートされます。テーブルの主キーには、自動的にインデックスが設定されます。フルテキスト検索では、重要な単語と、それらの単語の特定の列内での場所に関する情報が、フルテキスト インデックスに格納されます。
- 制約
- テーブル列に割り当てられるプロパティ。特定の種類の無効なデータ値が列に格納されないようにします。たとえば、UNIQUE 制約または PRIMARY KEY 制約により、既存の値と重複する値を挿入できなくします。CHECK 制約により、検索条件に一致しない値を挿入できなくします。NOT NULL により、NULL 値を挿入できなくします。
- ストアド プロシージャ
- 事前コンパイルされた Transact-SQL ステートメントのコレクション。このコレクションには名前が付けられて格納され、1 つの単位として処理されます。SQL Server では、SQL Server の管理に使用するストアド プロシージャと、データベースとユーザーに関する情報の表示に使用するストアド プロシージャが用意されています。SQL Server で用意されているストアド プロシージャは、システム ストアド プロシージャと呼ばれます。
- ユーザー定義関数
- SQL Server では、ユーザーが定義した Transact-SQL 関数を指します。各ステートメントで同じロジックを何度もコーディングしなくて済むように、関数により、頻繁に実行されるロジックが、Transact-SQL ステートメントで呼び出せる名前付きエンティティにカプセル化されます。
データの管理
では、アプリケーションのデータ層とビジネス層の構築に入りましょう。データ コンポーネントを作成し、それらのコンポーネントにメソッドを追加し、さらに SQL Server Express にストアド プロシージャを追加する処理について詳しく見ていきます。
データ エクスプローラの内部でのデータ接続のセットアップ
第 1 部では、.MDF データベース ファイルを追加し、データ エクスプローラの内部でデータ接続を作成しました。次に進む前に、これらの手順を簡単に振り返ります。
.MDF データベース ファイルを追加するときに、(新しい Web サイトを作成したときに追加された) "Data" ディレクトリを右クリックし、[Add New Item] をクリックしました。ファイルの種類の一覧で、[Database] をクリックして、"StudentActivities.mdf" という名前に変更しました。データベースを追加した後で、データ エクスプローラが開かれ、新しい空のデータベースにアクセスするためのデータ接続が作成されました。
接続のセットアップが正常に終了した後で、"Data Connections" ルートの下にデータベース "StudentActivities" がツリー ビュー形式で表示されました。データベースのツリー ビューをたどっていくと、"Tables"、"Views"、"Stored Procedure"、"Functions"、"Synonyms"、"Types"、および "Assemblies" の一連のフォルダが表示されているのがわかります。

図 1. データ エクスプローラ
SQL Server Express のテーブルの使用
このデータベースにデータベースとデータ接続を追加したので、このデータベースのコンテンツを表示し、このデータベースに新しいテーブルを追加できます。データベースに含まれるすべてのテーブルを表示するには、"Tables" ノードを展開します。一連の "aspnet_" プレフィックスが付いたテーブルが表示されます。データ プロバイダとして "StudentActivites" データベースをセットアップしたときに、Web サイト管理ツールにより、これらのテーブルが追加されました。これらのテーブルには、ユーザー アカウントの資格情報、アプリケーション ロール、およびユーザー設定のすべてが格納されています。
2 つの単純なテーブルを作成して、履修状況に関するアプリケーション固有のデータをすべて格納する必要があります。最初に追加するテーブルはメイン テーブルで、"tblActivity" と呼ばれます。テーブルを追加するには、"Tables" ノードを右クリックし、[Add New Table] をクリックします。Visual Web Developer 2005 Express Edition のコーディング ペインに、3 つの基本列を備えた空のグリッドが表示されます。デザイナ グリッドの最初の列は、"Column Name" です。この列には、これから追加する列の名前が格納されます。次の列は "Data Type" と表示されていて、この列によってテーブルの列の型が指定されます。デザイン ビューの最後の列は "Allow Nulls" と表示されていて、この列によって、このフィールドに値が必要かどうかが定義されます。
履修科目テーブル
履修科目を定義するのに必要な列の作成から始めましょう。以下の定義に一致する一連の列を作成します。
| Column Name | Data Type | Allows Nulls |
|---|---|---|
| iActivityID | int | オフ |
| vcTitle | varchar | オン |
| vcDescription | varchar | オン |
| dtDateOfActivity | datetime | オン |
| vcStartTime | varchar | オン |
| vcEndTime | varchar | オン |
| iTotalSlots | int | オン |
| bIsPublished | bit | オフ |

図 2. tblActivity のデザイン ビュー
ここで、作成したものを確認して、さらに数行の列を定義します。最初に、各列の名前に注目します。各列には、プレフィックスが付き、列の内容を表す名前が付けられています。適切な名前付け規則に従うと、名前を見れば、その列またはオブジェクトの目的が理解できるようになります。つまり、"vcTitle" では履修科目のタイトルが保持されます。プレフィックスにも、説明の目的があります。プレフィックスは、データ型を説明する省略形です。その列に設定されることが期待されるデータ型が列名で説明されていると、後にユーザーがそのフィールドに無効な型の値を挿入しようとした場合に、そのエラーをトラブルシューティングするのに役立つことがよくあります。
このテーブルでは、4 つの異なるデータ型が利用されます。int、varchar、datetime、および bit です。int 型では、フィールドに格納できるのは整数値のみです。varchar は、可変長の文字列フィールドです。このフィールドでは、すべての英数値が有効です。datetime 型では、有効な日付と時刻のみを保持できます。時刻が指定されないと、既定値の "12:00.000 am" になります。bit データ型では、値 true または false のみを保持できます。
これでテーブルの構造はほぼ完成ですが、2 ~ 3 個のフィールドについて定義を追加する必要があります。まず、"iActivityID" フィールドを選択します。このフィールドは、主キーとして機能します。主キーは、各レコードを一意に定義する、一意レコード識別子です。データベース テーブルでは、1 つの列にのみ主キーを定義できます。このフィールドに主キーを設定するには、行セレクタを右クリックして、[Set Primary Key] をクリックします。主キーを設定すると、各行のその列には一意な値が保持されます。さらに、この列には NULL 値を格納できません。テーブルでは、主キーに NULL 値を格納することが許可されません。これに違反すると、エラーが発生します。挿入される各値が一意になることを保証するために、この値の挿入処理を SQL Server Express に行わせます。レコードが追加されるごとに、SQL Server Express によってこのフィールドが自動増分されるように定義します。デザイナ ペインの下には、[Column Properties] ペインがあります。"iActivityID" が選択された状態で、[Identity Specification] プロパティを展開し、[(Is Identity)] を [yes] に、[Identity Increment] を [1] に、[Identity Seed] を [1] に設定します。"(Is Identity)" プロパティにより、この列は ID 列なので一意になる必要があると定義されます。"Identity Increment" プロパティの指定により、テーブルに行が追加されるごとに、SQL Server Express によってプレビュー ID 値が 1 ずつ増加されます。"Identity Seed" プロパティにより、この自動増分値の開始位置が指定されます。実稼動アプリケーションでは、ユーザーは ID が 1 のレコードを希望せず、100000 で開始することを希望する場合があります。100000 で開始することで、各 ID の長さと外観の一貫性が長期間保持されることを保証できます。これは、インボイス システムなど、ID がユーザーに表示されるアプリケーションを作成する際に重要になる場合があります。今回のアプリケーションでは、アプリケーションのユーザーが ID 番号で履修科目を参照することはないので、1 で開始することは目的にかなっています。
次に、"vcDescription" フィールドを変更する必要があります。行セレクタをクリックします。[Column Properties] ペインでは、"varchar" フィールドの長さは 50 です。これは、フィールドで保持できるのは最大で 50 文字に限定されていることを意味しています。このフィールドは説明フィールドなので、より多数の文字を格納する必要があります。したがって、このフィールドの長さを 250 に変更します。
変更が必要な最後の列は、"bIsPublished" 列です。この列の行セレクタをクリックして選択し、[Column Properties] ペインに戻ります。[Default Value of Binding] に、「0」と入力します。既に説明したとおり、このフィールドは bit 型として定義されているので、格納できるのは値 [true] または [false] のみです。ここでも、bit 値のフィールドには NULL 値を格納できません。このフィールドに格納できる 2 種類の値のいずれでもないためです。[Default Value of Binding] プロパティの既定値を 0 に設定することにより、レコードの作成時に値が指定されないと、SQL Server Express によって自動的に値 [false] が挿入されます。
これで、履修科目テーブルの定義が完了しました。[Save] をクリックします。テーブル名を指定するように指示されます。「tblActivity」と入力して [OK] をクリックすると、テーブルが生成されます。このテーブルを表示するには、テーブルの一覧を更新する必要がある場合があります (データ エクスプローラで、"Tables" フォルダを右クリックし、[Refresh] をクリックします)。
テーブルのデータ コンテンツ (現在は空) の表示、データの追加、または既存のデータの変更を行うには、"tblActivities" テーブルを右クリックして、[Show Table Data] をクリックします。作成した定義に基づいて構成された列を備えたテーブルが表示されます。本来は、現在作成しているアプリケーションを使用して、このテーブルに新しいレコードを追加します。ここでは、手動で数個のレコードを入力して、データを表示します。"Baseball"、"Basketball"、および "Football" に数個のレコードを入力します。アプリケーションをビルドするときに、テーブルにデータを表示し、それらを選択できるようにするためです。"iActivityID" フィールドは ID フィールドなので、ここに手動でデータを入力することはありません。値を入力しようとすると、SQL Server Express により、値を設定できないことを示す警告エラーが生成されます。フィールドに値を入力する際は、各列に格納されるデータ型に注意します。これは、データ型をプレフィックスとして使った列名を設定したことによるメリットの 1 つです。
学生の履修状況テーブル
もう 1 つのテーブルを作成して、特定の履修科目の登録を管理する必要があります。データ エクスプローラで、"Tables" フォルダを右クリックし、[Add New Table] をクリックします。テーブルの以下の列を定義します。
| Column Name | Data Type | Allows Nulls |
|---|---|---|
| iUserActivityID | int | オフ |
| UserName | varchar | オフ |
| iActivityID | int | オフ |

図 3. tblUserActivity のデザイン ビュー
"tblActivity" の "iActivityID" と同様に、主キーおよびこのテーブルの ID 列として "iUserActivityID" をセットアップします。このテーブルは中間テーブルと呼ばれます。中間テーブルにより、2 つの既存のテーブルが結合され、これらのテーブルのデータ間の関係が管理されます。アプリケーションのユーザーを格納するために Web サイト管理ツールによって追加された "aspnet_Users" と "tblActivity" テーブルの間に、テーブルによって多対多の関係 (1 つの履修科目に 1 人以上の学生を割り当てることができ、その逆も可能であることを意味します) がセットアップされます。このテーブルの "UserName" 列は、"aspnet_Users" の "UserName" 列に直接関係します。"iActivityID" は、"tblActivity" の "iActivityID" フィールドへの外部キーとして機能します。外部キーは、テーブルに含まれ、別のテーブルの主キーを参照するキーです。このテーブルにより、"tblActivity" テーブルの履修科目が "aspnet_Users" のユーザーに関連付けられます。
[Save] をクリックして、このテーブルの名前を "tblUserActivity" に設定します。[OK] をクリックして、テーブルを作成します。
データ コンポーネント
履修状況のデータを格納するために必要な必須のテーブルがデータベースに作成されたので、2 つのデータ コンポーネントを作成して、データを接続する必要があります。データ コンポーネントは、ASP.NET 2.0 ソリューションです。このソリューションを使用して、n 層アプリケーションのアーキテクチャに適した、単純なコードなしの形式で、ビジネス オブジェクトを作成します。
n 層アーキテクチャは、単純に、アプリケーションが少なくとも 3 つの論理層に分割されることを意味します。最初の層はデータ層で、データベースや xml ファイルなどで表現されます。システムで管理されるすべてのデータの格納と取得に使用されます。2 番目の層は、アプリケーション/ビジネス層です。ここで、計算やルールの実施などのビジネス ロジックが処理されます。3 番目の層は、クライアント/プレゼンテーション層です。プレゼンテーション層の対象になるデバイスは、多岐にわたります。Web ブラウザ、Windows アプリケーション、個人用のパソコン、携帯電話などです。n 層アーキテクチャを利用することの利点は多数あり、この資料の範囲を超えています。n 層アーキテクチャでアプリケーションをデザインすることの利点の中でも簡単なものは、開発者が必要に応じて、1 つまたはいくつかの層を分類および再利用できることです。Web ブラウザと携帯電話を対象とするアプリケーションを記述する必要がある場合は、デバイスごとに別のプレゼンテーション層を作成する必要があります。ただし、プレゼンテーション層からビジネス ロジックを取り除けば、すべてのビジネス ロジックを共有できることになります。
このアプリケーションにより、すべてのデータ アクセス プロセスを処理する、2 つの異なるデータ コンポーネントがモデル化されます。最初に、"Activities" データ コンポーネントを作成します。このデータ コンポーネントでは、履修科目の作成、編集、削除、および表示に必要なすべてのデータ処理が行われます。2 番目に構成するデータ コンポーネントは、"StudentActivities" データ コンポーネントです。このデータ コンポーネントでは、履修科目での学生の登録と抹消、特定の学生の履修状況の表示、および特定の履修科目に登録された学生の表示が実行されます。
Activities データ コンポーネント
ソリューション エクスプローラで "Activities" オブジェクトを作成するには、ルート Web フォルダを右クリックして、新しい項目を追加します。[Data Component] をクリックして、名前を "ActivityDS.xsd" に変更します。[OK] をクリックします。Visual Web Developer 2005 Express Edition により、"Code" ディレクトリに配置する必要があることを示すメッセージが表示されます。[Yes] をクリックして、"Code" ディレクトリを作成し、そこにデータ コンポーネントを配置します (この "Code" ディレクトリは展開プロセスの不可欠な部分として機能します。詳細についてはこのシリーズの第 3 部で説明します)。最初の実行で、ASP.NET 2.0 により、このディレクトリに含まれるすべてのファイルがコンパイルされます。したがって、独立したコンパイル スクリプトが不要になります。
データ コンポーネントが追加されると、Data Component Configuration Wizard (DCCW) の支援により、オブジェクトが生成されます。ウィザードでは、最初にデータ接続を選択することを求められます。添付された .MDF ファイルに対して作成されたデータ接続を選択して、[Next] を 2 回クリックします。コマンドの種類を選択することを指示する画面が表示されたら、[Create New Stored Procedure] をクリックして、[Next] をクリックします。

図 4. Data Component Configuration Wizard - コマンドの種類
ウィザードにより、select ステートメントを入力するように求められます。クエリ ビルダを使用して、select ステートメントをビルドできます。または、次のように入力します。
SELECT * FROM tblActivity

図 5. Data Component Configuration Wizard - SQL ステートメント
SQL ステートメントを入力した後で、[Next] をクリックします。ウィザードにより、select、insert、update、および delete ストアド プロシージャの名前を入力するように求められます。select ストアド プロシージャには、「ActivitySelectAll_sp」と入力します。insert ストアド プロシージャには、「ActivityInsertOne_sp」と入力します。update ストアド プロシージャには、「ActivityUpdateOne_sp」と入力します。delete ストアド プロシージャには、「ActivityDeleteOne_sp」と入力します。ストアド プロシージャ名の入力が完了したら、[Next] をクリックします。ストアド プロシージャを生成するには、fill メソッドの名前を FillActivities に、get メソッドの名前を GetActivities に変更し、[Finish] をクリックします。データ エクスプローラで、ストアド プロシージャを更新します。

図 6. Data Component Configuration Wizard - ストアド プロシージャ名
Visual Web Developer 2005 Express Edition により、入力した select ステートメントに基づいて生成されたスキーマが解析されます。その結果、insert、update、および delete ストアド プロシージャが導き出されます。この資料の執筆中の時点では、この実装は完全ではありません。ASP.NET 2.0 により、オーバーロードされたメソッドが多数作成されるので、どのメソッドが insert、update、または delete に適しているかが不明確になります。実装を簡潔化するために、各 insert、update、および delete に対して 1 つのメソッドを明確に定義できるようにする回避策を調査する予定です。おそらく、Beta バージョンがリリースされるまでに、これらのオーバーロードされたメソッドはすべて削除されます。しかしここでは、DCCW を操作して開発者に適切な環境の制御を提供する方法を理解するための演習として、この回避策を実行します。
回避策を実装するには、DCCW によって生成されたストアド プロシージャである "ActivityInsertOne_sp"、"ActivityUpdateOne_sp"、および "ActivityDeleteOne_sp" を削除します。これらのストアド プロシージャを削除するには、データ エクスプローラで、"Stored Procedures" フォルダの適切なストアド プロシージャを右クリックし、[Delete] をクリックします。Data Component Configuration Wizard で、ストアド プロシージャを再作成し、各 insert、update、および delete を個別に処理するために明確に定義された新しいメソッドを追加します。新しいメソッドを追加するには、"ActivitiesTableAdapter" を右クリックして、[Add Query] をクリックします。以前に使用したものと同じ接続を使用して、[Next] をクリックします。コマンドの種類を選択し、[Create a new stored procedure] をクリックして、[Next] をクリックします。クエリの種類の一覧で [Insert] をクリックします。[Next] をクリックして、このメソッドを insert メソッド専用として定義します。再び [Next] をクリックして、次の insert SQL ステートメントを入力します。
INSERT INTO tblActivity(vcTitle, vcDescription, dtDateOfActivity, vcStartTime, vcEndTime, iTotalSlots, bIsPublished) VALUES( @vcTitle, @vcDescription, @dtDateOfActivity, @vcStartTime, @vcEndTime, @iTotalSlots, @bIsPublished)
[Next] をクリックして、ストアド プロシージャの名前を "ActivityInsertOne_sp" に変更し、[Next] をクリックします。メソッドの名前を "AddActivity" に変更し、[Finish] をクリックします。これでストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
update メソッドと delete メソッドについても、同様の手順を実行する必要があります。update メソッドを作成するには、クエリの種類の選択を求める画面が表示されるまで、ウィザードで上の手順を実行します。クエリの選択画面が表示されたら、[Update] をクリックし、[Next] をクリックします。その後、次の update SQL ステートメントを入力します。
UPDATE tblActivity SET vcTitle = @vcTitle, vcDescription = @vcDescription, dtDateOfActivity = @dtDateOfActivity, vcStartTime = @vcStartTime, vcEndTime = @vcEndTime, iTotalSlots = @iTotalSlots, bIsPublished = @bIsPublished WHERE iActivityID = @iActivityID
[Next] をクリックして、ストアド プロシージャの名前を "ActivityUpdateOne_sp" に変更し、[Next] をクリックします。メソッドの名前を "UpdateActivity" に変更し、[Finish] をクリックします。これでストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
delete メソッドを作成するには、ウィザードで上の手順を実行します。クエリの種類の選択を求められたら、[Delete] をクリックし、[Next] をクリックします。その後、次の delete SQL ステートメントを入力します。
DELETE tblActivity WHERE iActivityID = @iActivityID
[Next] をクリックして、ストアド プロシージャの名前を "ActivityDeleteOne_sp" に変更し、[Next] をクリックします。メソッドの名前を "RemoveActivity" に変更し、[Finish] をクリックします。これでストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
これで、基本的な select、insert、update、および delete ステートメントが正しくセットアップされました。渡された特定の条件に基づいて履修科目を返す、選択処理のメソッドを、あと 2 つ追加する必要があります。次に追加するメソッドにより、公開されたかどうかに基づいてフィルタ選択された履修科目を取得できます (登録状況の参照で使用できます)。
このメソッドを作成するには、Data Component Configuration Wizard で上の手順を実行します。クエリの種類で、[Select which returns rows] をクリックし、[Next] をクリックします。その後、次の select SQL ステートメントを入力します。
SELECT * FROM tblActivity WHERE bIsPublished = @bIsPublished
[Next] をクリックして、ストアド プロシージャの名前を "ActivitySelectByPublishing_sp" に変更し、[Next] をクリックします。fill メソッドの名前を "FillActivitiesByPublishing" に、get メソッドの名前を "GetActivitiesByPublishing" に変更します。[Finish] をクリックします。これで、ストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
最後に構成するメソッドでは、渡された履修科目の ID に基づいて、履修科目が返されます。このメソッドを作成するには、ウィザードで上の手順を実行します。クエリの種類で、[Select which returns rows] をクリックし、[Next] をクリックします。その後、次の select SQL ステートメントを入力します。
SELECT * FROM tblActivity Where iActivityID = @iActivityID
[Next] をクリックして、ストアド プロシージャの名前を "ActivitySelectOne_sp" に変更し、[Next] をクリックします。fill メソッドの名前を "FillActivitiesByID" に、get メソッドの名前を "GetActivitiesByID" に変更します。[Finish] をクリックします。これで、ストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
コンポーネントの名前を変更するには、データ テーブルの最上部を右クリックし、名前を "Activities" に変更します。テーブル アダプタの名前は、自動的に "ActivitiesTableAdapter" に更新されます。[Property] ウィンドウで、ドロップダウン リストから [Activities] データ セットを選択し、[Name] プロパティの名前を "dsActivities" に変更し、データ セットとデータ テーブルの間の名前の競合を回避します。

図 7. Activities データ コンポーネントのデザイン ビュー
これで、最初のビジネス オブジェクトが正常に完成しました。
StudentActivities データ コンポーネント
"StudentActivities" データ コンポーネントの作成は、Activities データ コンポーネントに非常に似ています。2 つの異なるビジネス オブジェクトが必要な理由は、"StudentActivities" データ コンポーネントのテーブル スキーマが、"Activities" データ コンポーネントとわずかに異なるためです。返される列の一部が異なります。
新しいデータ コンポーネントを "Code" ディレクトリに追加し、名前を "StudentActivites.xsd" に変更します。Data Component Configuration Wizard が起動されたら、"Activities" データ コンポーネントのセットアップと同じ手順を実行します。指示に従って、次の select SQL ステートメントを入力します。
SELECT iUserActivityID, a.*, UserName
FROM tblUserActivity ua
INNER JOIN tblActivity a ON ua.iActivityID = a.iActivityID
[Next] をクリックします。select ストアド プロシージャの名前を "ActivitySelectAllByUser_sp" に、insert ストアド プロシージャの名前を "ActivityInsertByUser_sp" に、update ストアド プロシージャの名前を "ActivityUpdateByUser_sp" に、delete ストアド プロシージャの名前を "ActivityDeleteByUser_sp" に変更し、[Next] をクリックします。fill メソッドの名前を "FillAllActivitiesByUser" に、get メソッドの名前を "GetAllActivitiesByUser" に変更して、[Finish] をクリックします。これで、"StudentActivities" データ コンポーネントのすべてのストアド プロシージャとメソッドが生成されます。
先ほど説明した回避策を実行するには、ストアド プロシージャ "ActivityInsertByUser_sp"、"ActivityUpdateByUser_sp"、および "ActivityDeleteByUser_sp" を削除し、ウィザードを使用して手動で再度追加します。
insert メソッドを作成するには、"Activities" データ コンポーネントの insert メソッドの作成と同じ手順を実行します。指示に従って、次の insert SQL ステートメントを入力します。
INSERT INTO tblUserActivity (UserName, iActivityID) VALUES (@UserName, @iActivityID)
[Next] をクリックして、ストアド プロシージャの名前を "ActivityInsertByUser_sp" に変更し、[Next] をクリックします。メソッドの名前を "AddEnrollment" に変更し、[Finish] をクリックします。これでストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
delete メソッドを作成するには、"Activities" データ コンポーネントの delete メソッドの作成と同じ手順を実行します。指示に従って、次の delete SQL ステートメントを入力します。
DELETE tblUserActivity WHERE iUserActivityID = @iUserActivityID
[Next] をクリックして、ストアド プロシージャの名前を "ActivityDeleteByUser_sp" に変更し、[Next] をクリックします。メソッドの名前を "RemoveEnrollment" に変更し、[Finish] をクリックします。これでストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
これで、select、insert、および delete ステートメントが正しくセットアップされました。このデータ コンポーネントには、update メソッドは必要ありません。一般的に、"tblUserActivity" などの中間テーブルの処理で実行する操作は、レコードの追加および削除のみであるためです。渡された特定の条件に基づいて履修状況のレコードを返す select メソッドを、あと 2 つ追加する必要があります。次に追加するメソッドにより、特定の学生が登録しているすべての履修科目を取得できます。
このメソッドを作成するには、"Activities" データ コンポーネントでの select メソッドの追加と同じ手順をウィザードで実行します。クエリの種類で、[Select which returns rows] をクリックし、[Next] をクリックします。その後、次の select SQL ステートメントを入力します。
SELECT ua.iUserActivityID, a.*, ua.UserName FROM tblUserActivity ua INNER JOIN tblActivity a ON ua.iActivityID = a.iActivityID WHERE ua.UserName = @UserName
[Next] をクリックして、ストアド プロシージャの名前を "ActivitySelectByUser_sp" に変更し、[Next] をクリックします。fill メソッドの名前を "FillActivitiesByUser" に、get メソッドの名前を "GetActivitiesByUser" に変更し、[Finish] をクリックします。これでストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
最後に構成するメソッドでは、特定の履修科目について、すべての登録している学生の一覧が返されます。このメソッドを作成するには、ウィザードで上の手順を実行します。クエリの種類で、[Select which returns rows] をクリックし、[Next] をクリックします。その後、次の select SQL ステートメントを入力します。
SELECT ua.iUserActivityID, a.*, ua.UserName FROM tblUserActivity ua INNER JOIN tblActivity a ON ua.iActivityID = a.iActivityID WHERE ua.iActivityID = @iActivityID
[Next] をクリックして、ストアド プロシージャの名前を "ActivitySelectByRoster_sp" に変更し、[Next] をクリックします。fill メソッドの名前を "FillActivitiesByRoster" に、get メソッドの名前を "GetActivitiesByRoster" に変更し、[Finish] をクリックします。これでストアド プロシージャが生成され、データ コンポーネントにメソッドが追加されます。
コンポーネントの名前を変更するには、データ テーブルの最上部を右クリックし、名前を "StudentActivities" に変更します。テーブル アダプタの名前は、自動的に "StudentActivitiesTableAdapter" に更新されます。[Property] ウィンドウで、ドロップダウン リストから [StudentActivities] データ セットを選択し、[Name] プロパティの名前を "dsStudentActivities" に変更し、データ セットとデータ テーブルの間の名前の競合を回避します。

図 8. StudentActivities データ コンポーネントのデザイン ビュー
これで、2 つのオブジェクト (Activities と StudentActivities) で構成されるビジネス層が完了しました。このシリーズの第 3 部では、データ コンポーネントと接続する Web フォームをビルドします。このシリーズのデータ アクセスの部分を完了する前に、ASP.NET 2.0 のもう 1 つの技術革新である、データ ソースについて簡単に説明します。
データ ソース
データ ソースは、選択、挿入、更新、および削除などの基本的なデータ機能を、コモン コントロールにラップするサーバー コントロールです。これらのコントロールが、データ層またはビジネス層とプレゼンテーション層との間の橋渡しとして機能することにより、単純な "コードを必要としない" のデータ バインドが開発者に提供されます。
ASP.NET 2.0 により、以下の 6 種類のデータ ソースが導入されます。
- AccessDataSource は、Access データベースへの接続を表します。返されるデータは表構造になっています。
- DataSetDataSource は、DataSet オブジェクトの XML 表現として機能します。名前から得られる印象と異なり、このデータ ソースは、この資料の前半で作成したデータ セットに直接接続されません。また、DataSetDataSource は階層型の XML に基づいているにもかかわらず、返されるデータは表構造になっています。
- ObjectDataSource は、データを返すカスタム .NET ビジネス オブジェクトにバインドされます。これは、データ コンポーネントとの接続に使用するデータ ソースです。このコントロールは、ビジネス オブジェクトに接続している n 層アーキテクチャに接続されます。返されるデータは表構造になっています。
- SQLDataSource は、SQL データを返す ADO.NET データ プロバイダへの接続を表します。SQLDataSource では、返されるデータは表構造になっています。
- SiteMapDataSource では、サイトマップ ファイルからデータが取得されます。SiteMapDataSource では、返されるデータは階層構造になっています。
- XMLDataSource により、ファイル、URL、または文字列から XML が読み込まれます。XMLDataSource コントロールでは、返されるデータは階層構造になっています。
このアプリケーションに対しては、ObjectDataSource と SiteMapDataSource のみを使用します。このシリーズの第 3 部では、これらのデータ ソースを構成してデータ コンポーネントと接続する方法、およびこれらのデータ ソースをサーバー コントロールにバインドする方法について詳細に説明します。
まとめ
SQL Server Express と Visual Web Developer 2005 Express Edition とがシームレスに統合されることにより、データ コンポーネントとデータ ソースが導入され、この 2 つを使って n 層アーキテクチャを簡単に構築できるようになります。データ コンポーネントは、"コードを必要としない" のビジネス オブジェクトを作成するための ASP.NET 2.0 ソリューションです。ObjectDataSource コントロールにより、バインドされたデータ コントロールとデータ コンポーネントの間のデータ フローが管理されます。次の部では、フロント エンド Web フォームの構築を開始する際の ObjectDataSource の実装の詳細について説明します。
Dan Burman
は、ニューヨークを拠点とするカスタム ソフトウェア会社 Citigate Hudson のコンサルタントです。Citigate Hudson
は、Microsoft Gold Certified Partner for Business Intelligence です。Citigate Hudson
の
Web サイトを参照してください。