2012年4月19日木曜日

Questionnaire Web サービス


Leendert Versluijs, Software Engineer
Jeroen Huitink, Infrastructure Engineer
Sander Duivestein, Public Relations
Cap Gemini Ernst & Young

March 19, 2002
日本語版最終更新日 2003 年 6 月 6 日

要約 : Questionnaire Web サービスの機能とデザインについて説明します。Questionnaire Web サービスは、不動産 Web アプリケーション Jaggle のコンポーネントの 1 つであり、ユーザーの製品抽出条件を定義するための反復的な質問セットを、Web サイトのインターフェイスを通じたユーザーとのやり取りによって生成するための汎用的なメカニズムを提供します。

概要説明
必要条件
分析とデザイン
Questionnaire のクラス
設計方針
適用されているデザイン パターン
便利な機能

概要説明

Questionnaire Web サービスは、関連する質問のセットを生成するための汎用的なメカニズムを提供することを目的としています。 次の図は、不動産アプリケーション Jaggle の全体的なアーキテクチャにおける Questionnaire Web サービスの位置付けを表しています。

図 1. 不動産アプリケーション Jaggle の中の Questionnaire Web サービス

ユーザーのニーズに合った不動産の検索を開始するために、まず Web サイトが、一連の質問を含むフォームをユーザーに提示します。 この質問に対するユーザーの回答に基づいて、Questionnaire Web サービスは、ユーザーの抽出条件をさらに絞り込むための新しい質問セットを生成します。 Web サイトと Web サービスとの間で、アンケート プロセスと呼ばれるこの質問と回答のサイクルが繰り返され、最終的には明確に定義された回答のセットが導き出されて Web サイトに送られます。 Web サイトは、その回答を使って抽出条件を生成し、それに基づいて Matching Web サービスが製品を検索します。

必要条件

Questionnaire Web サービスの必要条件は、ビジネス文書から引き出されます。 Questionnaire Web サービスには、以下の機能が要求されます。

  1. 質問の要求を受け付ける。
  2. 質問のグループを検索する。
  3. 質問のグループを通して見る。
  4. 通して見て、その終了を判断する。
  5. 質問と回答を保持する。
  6. 回答を格納する。
  7. 回答を取得する。

分析とデザイン

ユース ケース

Questionnaire Web サービスの中心的なアクタは、Web サイトのソフトウェア部分です。 次の図は、Web サイト アクタと Questionnaire Web サービスとのやり取りのユース ケースの概要です。

図 2. Web サイト アクタと Questionnaire Web サービスとのやり取りのユース ケース

アクティビティ図

次のアクティビティ図は、アンケート プロセスの概要を示しています。この図は、ユース ケース内のアクティビティの詳細をカバーしています。 Web サイト アクタがアンケート プロセスをトリガし、プロセスのワークフローを促進します。

図 3. アンケート プロセスのアクティビティ

クラス図

次の UML (Unified Modeling Language) クラス図は、Questionnaire Web サービスのクラスおよびクラス間の関係の概要を示すオブジェクト モデルを表しています。 オブジェクトは、Facade クラス、ビジネス ルール クラス (GroupCursorGroupQuestion、および Answer の各オブジェクト) 、およびデータ アクセス クラス (StoreDataRetrieveData、および DBConnection) に分類できます。 このモデル内のオブジェクトについては、この後の「Questionnaire のクラス」で詳しく説明します。

図 4. Questionnaire Web サービスのクラスとその関係 (拡大するには画像をクリックしてください)

シーケンス図

次の図は、Questionnaire のクラスの主要なシーケンスを表しています。 Questionnaire のクラスのやり取りはこれ以外にも考えられますが、グループ内の質問と回答の要求および格納のために Web サイトによって開始される主要なシーケンスはこの図のとおりです。

図 5. Questionnaire のクラスの主要なシーケンス (拡大するには画像をクリックしてください)

データ モデル

Questionnaire Web サービスに関連付けられているデータベースは、次の図に示すデータ モデルに基づいています。 この論理データ スキーマは正規化されています。 Groups、Question、Answer、および UserAnswer の各テーブルは、オブジェクト モデルから抽出できます。

図 6. Questionnaire Web サービスのデータ モデル (拡大するには画像をクリックしてください)

各テーブルの詳細については、次の表を参照してください。

表 1. データ モデルの説明

テーブル 説明
Groups Questionnaire Web サービスの質問と回答は、Groups テーブルにグループ化されています。 グループの中に別のグループを含めたり (Id/ParentId の構造) 、異なる質問セットに複数のルート グループを指定したりできます。 グループは質問と回答のセットであり、グループのセットは、特定のアンケート プロセスの質問と回答の包括的なセットです。 グループのセットは、Questionnaire の質問の流れを表します。この質問の流れは、アクティビティ図のループに相当します。
Question 質問が開いた質問タイプの場合は、あらかじめ定義された回答を 1 つ以上持つことができます。これに対して、閉じた質問タイプの回答は 1 つだけです。
QuestionType 質問にはさまざまなタイプがあります。

開いた質問タイプ には以下のものがあります。
Character = 回答がテキストになる質問タイプ
Numeric = 回答が数値になる質問タイプ
Bigger = "より大きい" という質問
Between = 回答が 2 つの値の間になる質問
Smaller = "より小さい" という質問
DateType = 回答が日付形式になる質問タイプ
BiggerDate = "何日より後" という質問
BetweenDate = "何日から何日まで" という質問
SmallDate = "何日より前" という質問

閉じた質問タイプ には以下のものがあります。
Multiple = 多項選択式で単一選択の質問 (ドロップダウン リストまたはオプション ボタン)
MultipleBetween = 多項選択式で範囲選択の質問
MultipleSelect = 多項選択式で複数選択の質問 (チェック ボックス)

Answer 多項選択式の閉じた質問に対する回答です。
UserAnswer グループに対する特定のユーザーの回答です。

Questionnaire のクラス

Questionnaire のすべてのクラスは、Jaggle.Questionnaire 名前空間に含まれています。 Questionnaire のクラスは 3 つのグループに分けることができます。 インターフェイス クラス、ビジネス ルール クラス、およびデータ アクセス クラス の 3 つです。 次の図は、これらクラスの実装を担う層とコンポーネントの対応を表しています。

図 7. クラスの実装を担う層とコンポーネントの対応


制約条件の理論は何ですか

Facade 層

Facade クラスの記述にあたっては、Facade を通じてインターネット経由で Web サービスを利用できるようにするのに必要な基礎部分は、すべて .NET Framework によって用意されます。 これには、サービス側の Microsoft® Internet Information Server (IIS) のリスナの作成や、Web 標準 SOAP への準拠に必要な WSDL (Web Service Description Language) ファイルと XML データの生成などが含まれます。 Facade クラスは、基になるより複雑な Questionnaire サブシステムをラップしています。

Facade クラス

Facade クラスは、LAN 環境でこのコンポーネントにアクセスする他のクラスのための主要なインターフェイスです。 次の表は、Facade クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 2. Facade クラスの関数

関数名 関数のスコープ 引数 戻り値 説明
GetRootId Public ByVal GroupsName As String String GroupsName によって識別される特定のグループ セットのルートを返します。
GetGroups Public ByVal GroupsName As String String グループのセットを XML 形式で取得します。グループには質問と回答が含まれています。
GetGroupsSchema Public   String グループ セットの XSD スキーマを取得します。
GetQuestions Public ByVal GroupId As String String 特定のグループの質問と回答を XML 形式で取得します。
GetQuestionsSchema Public   String 特定の質問と回答のグループの XSD スキーマを取得します。
GetAnswers Public ByVal GroupsName As String, ByVal UserId As String String 特定の質問グループに対する特定のユーザーの回答を XML 形式で取得します。
StoreAnswers Public ByVal GroupId As String, ByVal Answers As String String 特定のグループに対する特定のユーザーの回答を保存します。回答は XML 形式で保存されます。
GetAnswersSchema Public   String StoreAnswers の XSD スキーマを取得します。

ビジネス ロジック層

ビジネス ロジック層は 1 つのコンポーネントを定義します。このコンポーネントには、Questionnaire Web サービス サブシステムのビジネス ロジックをカバーする一連のビジネス ルール クラスが含まれています。 ビジネス ルールは、データセットを操作してロジックを実行します。 この場合のデータセットは、データ アクセス層によって取得された、切断された XML オブジェクトです。 実装されるビジネス ルールは、主に、基になるデータへのアクセスを BusinessFacade に提供するデータセット上の薄い層です。 たとえば、ビジネス ルール クラスは、Iterator デザイン パターン (この後の「適用されているデザイン パターン」を参照) を使用するオブジェクトを提供します。 ビジネス ルールのより複雑な実装例となるのが Group クラスです。 このクラスは、特定の質問グループに対する回答を格納します。 さらに、エキスパート システム ルールに基づいて、グループ セットの中から次の質問グループを決定します。 この決定は、格納されている回答に基づいて行われます。

GroupCursor クラス

GroupCursor クラスは、質問と回答 (ユーザーが選択できる回答) のグループのセットへのアクセスを提供します。 グループには別のグループを含めることができますが、その関係を示すのがこのクラスです (Root 関数と Child 関数を参照) 。 GroupCursor クラスは、Group クラスのエントリ ポイントです。 次の表は、GroupCursor クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 3. GroupCursor クラスの関数

関数名 関数のスコープ 引数 戻り値 説明
New Public overloads ByVal GroupsName as string   コンストラクタ。 GroupsCursor が GroupsName で初期化されます。GroupsName は、関連するグループのセットに対する一意の識別子です。
New Public overloads     コンストラクタ。 関連するグループのすべてのセットに対して GroupsCursor が初期化されます。
Retrieve Private     質問と回答のグループのセットを取得します。 このセットは、関連するグループの階層構造になっています。現状では、1 つのグループに含めることができるグループは 1 つだけです。
GroupData Public   String 質問と回答のグループのセットを XML 形式で返します。
GroupSchema Public   String GroupData の XSD スキーマを返します。GroupData は、質問と回答のグループのセットです。
Selects Public ByVal GroupId as string GroupCursor GroupID でグループを選択します。
GetSelection Public ByVal GroupId as string Group GroupID でグループを選択します。
Root Public   GroupCursor 特定のルート グループを GroupCursor として返します。
GetRoot Public   Group 特定のルート グループを Group として返します。
Child Public   GroupCursor GroupCursor 内を移動するための再帰関数です。現状では、1 つのグループに含めることができるグループは 1 つだけです。
GetChild Public   Group アクティブなグループを選択します (RootChild で選択) 。
RetrieveAnswers Public ByVal UserId as string String GroupsName で識別されるグループのセットに対する、指定されたユーザーのすべての回答を返します。

Group クラス

Group クラスは、Question クラスにアクセスするためのエントリ ポイントです。 次の表は、Group クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 4. Group クラスの関数


グループの成功への要因何ですか?
関数名 関数のスコープ 引数 戻り値 説明
New Public ByVal GroupId as string   コンストラクタ。 Group が GroupId で初期化されます。GroupId は、特定のグループに対する一意の識別子です。
Retrieve Private     1 つのグループ内の質問と回答のセットを要求します。
GroupData Public   String 質問と回答のグループを XML 形式で返します。
GroupSchema Public   String GroupData の XSD スキーマを返します。GroupData は、特定の質問と回答のグループです。
RetrieveAnswers Public ByVal UserId as string String 特定のグループに対する特定のユーザーの回答を取得します。
StoreAnswers Public ByVal AnswersXML as string String 特定のユーザーの回答をアーカイブし、セット内の次のグループの GroupId を返します。
AnswersSchema Public   String StoreAnswers 関数を使って与えられた回答の XSD スキーマを返します。
QuestionsCount Public   Integer グループ内の質問の数を取得します。数は 1 からカウントされます。
Id Public ReadOnly property   String アクティブなグループの一意の識別子を返します。
Name Public ReadOnly property   String アクティブなグループの名前を返します。

Question クラス

Question クラスは、特定の質問に対する特定のアクセスを提供します。 Question クラスは、Answer クラスにアクセスするためのエントリ ポイントです。 次の表は、Question クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 5. Question クラスの関数

関数名 関数のスコープ 引数 戻り値 説明
New Public ByVal Index as integer, ByRef Group as DataSet   コンストラクタ。 序数 (インデックス) によって識別される特定の質問を初期化します。
AnswersCount Public   Integer この質問に対する回答の数を取得します。数は 1 からカウントされます。
Id Public ReadOnly property   String アクティブな質問の一意の識別子を返します。
Type Public ReadOnly property   QuestionType アクティブな質問のタイプ識別子を返します。
QuestionType Public Enum
Character = 1
Numeric = 2
Multiple = 3
Bigger = 4
Between = 5
Smaller = 6
DateType = 7
BiggerDate = 8
BetweenDate = 9
SmallDate = 10
MultipleBetween = 11
MultipleSelect = 12
End Enum
    これらは質問のタイプです。詳細については、3.1.4 を参照してください。
Value Public ReadOnly property   String アクティブな質問のテキストを取得します。
MaxLength Public ReadOnly property   Integer アクティブな質問の最大長を返します。
MinValue Public ReadOnly property   Long アクティブな質問の最小値を返します。
MaxValue Public ReadOnly property   Long アクティブな質問の最大値を返します。
Required Public ReadOnly property   Boolean アクティブな質問の回答が必須かどうかを返します。

Answer クラス

Answer クラスは、開いた質問タイプの特定の回答に対する特定のアクセスを提供します。 次の表は、Answer クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 6. Answer クラスの関数

関数名 関数のスコープ 引数 戻り値 説明
New Public ByVal Index as Integer, ByRef Answers as DataRow()   コンストラクタ。 序数 (インデックス) によって識別される特定の回答を初期化します。
Id Public ReadOnly property   String この回答の一意の識別子を返します。
Value Public   String この回答の値を取得します。

データ アクセス層

データ アクセス層は、ビジネス コンポーネントからの要求を待ち受けるステートレスなコンポーネントにすぎません。 データ アクセス層の役割は、基になるデータベースからできるだけ早くデータを取得することです。 取得したデータは、切断されたデータセット (SYSTEM.DATA 名前空間) として上の層に渡されます。

DbConnection クラス

次の表は、DbConnection クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 7. DbConnection クラスの関数

関数名 関数のスコープ 引数 戻り値 説明
BuildDBConn Friend Shared   OleDbConnection データベース接続を初期化します。

RetrieveData クラス

次の表は、RetrieveData クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 8. RetrieveData クラスの関数


中央銀行が金利を引き上げる理由
関数名 関数のスコープ 引数 戻り値 説明
GroupSet Public ByVal GroupsName as string DataSet 質問と回答のグループのセットを取得します。
GroupSetAnswers Public ByVal UserId as string, ByVal GroupsName as string DataSet 質問のグループのセット (GroupsName で識別) に対する特定のユーザーの回答を取得します。
Group Public ByVal GroupId as string DataSet 特定の質問と回答のグループ (GroupId で識別) を取得します。
GroupAnswers Public ByVal UserId as string, ByVal GroupId as string DataSet 質問のグループ (GroupId で識別) に対する特定のユーザーの回答を取得します。
UserAnswers Public ByVal UserId as string DataSet 特定のユーザーのすべての回答を取得します。
NextGroups Public ByVal GroupId as string DataSet グループ セット内の次のグループを取得します。

StoreData クラス

次の表は、StoreData クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。

表 9. StoreData クラスの関数

関数名 関数のスコープ 引数 戻り値 説明
GroupAnswers Public ByVal AnswersXML as string   特定のグループに対する特定のユーザーの回答 (XML メッセージの一部) を格納します。
GetAttribute Private ByRef AnswerElement as XmlElement, ByRef Name as string String ヘルパ関数が XML 要素の属性を収集します。

設計方針

ワンストップ ショッピング

Facade クラスによって、1 回の呼び出しで Questionnaire の機能にアクセスすることが可能になります。 Facade を介さずに、Group クラスを使って質問と回答のグループにアクセスする場合は、複数の呼び出しが必要になります。 つまり、グループ コンストラクタを呼び出して、特定のグループを選択し、質問と回答を反復処理しなければなりません。 Questionnaire のクラスがインストールされているコンピュータでは直感的なインターフェイスを利用できますが、インターネット経由で Web サービスとしてアクセスする場合は、1 回の呼び出しで済む方が便利です。 特定のグループで利用できる質問と回答は、Facade を呼び出すことによって調べることができます。Facade は、すべての質問と回答を含む XML 形式の文字列を返します。

XML 形式

Questionnaire の Facade から要求される質問と回答は XML ベースです。 Web サービスから呼び出し側に送られるこの XML データは、プレーンな文字列です。 XML データを文字列型として送ることによって、他のプラットフォームでも Questionnaire Web サービスを呼び出すことができるようになります。 SYSTEM.DATA のデータセットの形式でデータを送ることも可能ですが、他のプラットフォームからのアクセスが困難になります。 データセットは、インターフェイスの背後で XML 形式のデータも格納しています。 文字列型で使用している XML 形式もこれと同じであるため、XML 文字列を取得してそれをクライアント データセットに格納することができます。

ステートレスとステートフル

スケーラブルなシステムを構築するために、可能な限りステートレスなプログラミング モデルに即した開発が行われました。 しかし、 Facade の下のクラスではメンバ変数を使用する (ステートフルにする) 必要性が高く、そうしないと、たとえばグループ内の 2 つの質問を取得するのにわざわざデータセットを再構築しなければならなくなってしまいます。これでは理想的な選択肢とはとてもいえません。 Facade はワンストップ ショッピングをサポートするため、メンバ変数がアクティブなのは Facade で必要な間だけです。しかもそれは、すべての質問と回答の XML データを 1 度に取得するためのごく短い時間です。 接続オブジェクトは、クラスのライフサイクル全体を通じてステートフルに保つ必要はありません。これは、接続プールの効率のためです。

データベースの問題

パフォーマンス上の理由から、データベースへのラウンドトリップは可能な限り避けています。

Group クラスを使用すると、質問に対する特定のユーザーの回答の XML スキーマを調べることができます。 つまり、GetAnswersSchema 関数を使用して、StoreAnswers 関数を使って与えた回答の XSD スキーマを取得できます。 このスキーマは、SYSTEM.DATA 名前空間によって生成されます。 いったんこの操作が行われると、スキーマを含むファイルがディレクトリに書き込まれます。次にユーザーが GetAnswersSchema 関数を呼び出して回答の XML スキーマを要求したときには、このファイルが使用されるためラウンドトリップは必要ありません。

現状では、Questionnaire でストアド プロシージャは使用されていません。これは、パフォーマンス上の問題がなかったためです。 しかし、今後パフォーマンスに問題が出た場合は、ストアド プロシージャが、Questionnaire の速度を改善するための最初の選択肢の 1 つとなるでしょう。 また、メンテナンスの観点から、すべての SQL を Questionnaire のソース コードに含めることにしました。 当然のことながら、システムのパフォーマンスは実際の状況下で監視する必要があります。

参照渡し

Microsoft® Visual Basic® .NET では、パラメータの既定の引き渡し方法が新たに値渡し (ByVal) になっています。 しかし、クラス内では、パラメータを参照渡しで引き渡す方が効率的です。このため、プライベート関数とサブルーチンのパラメータには ByRef を使用することにしました。

エラー処理

多くの場合、発生する可能性のあるエラーをすべてテストするより try-catch 構造を使う方が簡単です。 たとえば、ある関数がテーブル行の内容を取得するシナリオでは、目的の行がテーブルに含まれているかどうかを確認するコードを書くという選択肢が考えられます。 しかし、その行にアクセスしてエラーが発生するかどうかを調べるという方法もあります。 後者の方がより簡単で、効率的な場合も多いため、今回は後者を採用しています。 しかし、この設計方針が常に有効であるとは限りません。たとえば、アルゴリズムを正しく機能させるためには、チェックしなければならないエラーもあります。 ソース コードで try-catch ブロックをチェックし、この設計方針が適用されている箇所を確認してください。

Facade の背後で発生したエラーは、Facade のレベルまで上がってきます。 コンポーネントを通過したエラーは .NET エラー オブジェクトによってトレースされるため、Facade の背後で発生したすべてのエラーをキャッチする必要はありません。 エラーはすべて、Facade レベルで Windows® イベント ログによって記録されます。


インターネット経由で Questionnaire Web サービスを呼び出すクライアント (Facade を使用するクライアント) は、間違った形式のデータを送信してエラーを引き起こす可能性があります。 このような場合に、エラーの原因を知らせるエラー メッセージをクライアント開発者に送ることには意味があります。 しかし、Questionnaire Web サービス自体または Questionnaire Web サービスが送信するデータによって発生したエラーに関するエラー メッセージは、クライアント開発者に送ってもあまり意味はありません。 たとえば、数値フィールドに文字列値を格納するという誤りを指摘する SYSTEM.DATA エラーはクライアント開発者にとって有用ですが、データベース接続の問題に関するエラー メッセージをクライアント開発者に送っても意味はありません。データベース接続のエラーはクライアントによって発生したわけではないからです。 このように、クライアントの役に立つエラー メッセージとそうでないエラー メッセージを区別することは大切ですが、今回は、実際上の理由から、すべてのエラー メッセージをクライアントのレベルまで上げて、有用性の判断はクライアント開発者に委ねることにしました。

構成情報

.NET では、構成情報をレジストリに格納することもできますが、XML 形式の外部構成ファイルに格納することが推奨されています。 今回は、SYSTEM.CONFIGURATION 名前空間を使って、Questionnaire を使用する Web サービスの実行可能ファイルと同じディレクトリにある .config ファイル (projectname.exe.config または web.config) から構成情報を取得することにしました。 このファイルの内容は、次のようになっています。

                   

リテラル

ソース コード内でのリテラル (ハードコーディングされた文字列) の使用は許容されています。 たとえば、SQL XPath クエリの作成にリテラル文字列を使用すると、保守がしやすくなり読みやすさも向上します (実用的な議論) 。 複数回にわたって使用されるエラー説明やリテラル文字列は、定数になっています。

適用されているデザイン パターン

Facade デザイン パターン

Questionnaire のビジネス ロジックをカプセル化するために、Facade デザイン パターンを適用しています。 この Facade は、ビジネス コンポーネントやパートナー Web サイトがインターネット経由で使用するだけでなく、ローカルでアクセスすることもできます。 ローカルで使用する場合、SOAP インターフェイス (Web サービス) を通じてインターネット経由でアクセスするより直接コンポーネントを呼び出す方が常に高速であるため、パフォーマンス上の利点があります。 Facade デザイン パターンは、構造に関するパターンの 1 つです。 構造に関するパターンは、クラスやオブジェクトを組み合わせてより大きな構造を形成するための方法を扱います。 Facade デザイン パターンは、複雑なサブシステムの一連のインターフェイスに対する、統一されたシンプルなインターフェイスを提供します。

Iterator デザイン パターン

Iterator デザイン パターンは、行動に関するパターンであり、Questionnaire Web サービス サブシステム内のクラス間の通信を記述します。 このデザイン パターンを使用することによって、Questionnaire を使用する開発者が、Question クラスの Answer クラスや Group クラスの Question クラスを反復処理できるようになります。 今回は、IEnumerator インターフェイスと IEnumerable インターフェイスを使用して、System.Collections 名前空間の .NET Framework 部分に組み込まれている Iterator デザインを利用しています。

便利な機能

Iterator デザイン パターン

Iterator デザイン パターンは、SYSTEM.COLLECTIONS 名前空間を使って簡単に実装できます。 Group クラスと Question クラスで反復処理のインターフェイス (IEnumerableIEnumerator) を実装することによって、次のコードが可能になります。

 For Each Question In Group    Console.WriteLine Question.ValueFor Each Answer In Question       Console.WriteLine Answer.Value    Next Next  

階層構造の XML

.NET Framework のデータセットには、データベースから複数のテーブルを格納できます。 .NET Framework の便利な機能の 1 つといえるのが、こうしたデータセット内のテーブルの間のビルド関係です。 いったんこの関係が作成されると、階層構造のデータセットを利用できます。 これは、以前のバージョンの Microsoft® ActiveX® データ オブジェクト (ADO) のシェイプに似ています。 以下に例を示します。

 oRelation = oGroup.Relations.Add("QARelation", _  oGroup.Tables("Question").Columns("Id"), _  oGroup.Tables("Answer").Columns("QuestionId")) oRelation.Nested = True  

データセットは、背後でデータを XML ドキュメントに格納します。 上のコードを記述すると、テーブルを階層状に接続する XML ドキュメントが作成されます。

コンストラクタ関数のオーバーロード

関数のオーバーロードとコンストラクタは、Microsoft® Visual Basic® .NET の新しい機能です。 関数をオーバーロードすると、名前が同じでパラメータと動作が異なる複数の関数をソース コードで使用できます。 コンストラクタは、パラメータとして渡された値でクラスをインスタンス化します。

コンストラクタも関数の 1 つであるため、オーバーロードすることができます。その際には、overloads キーワードを使用する必要はありません。 以下に例を示します。

 Public Sub New() Public Sub New(ByVal GroupsName As String)  

共有メンバ

共通言語ランタイム (CLR) は、共有メンバをサポートしています。 共有メンバとは、所属するクラスのインスタンスを作成しなくてもアクセスできる関数です。 Visual Basic .NET では、共有メンバはモジュールレベルの関数に似ています。モジュール レベルの関数は、インスタンスを作成する必要なくアプリケーション全体で使用できます。

ファイル アクセス

データベースへのラウンドトリップを避けるために、特定のユーザーの回答を格納するテーブルの XSD スキーマが自動的に生成され、ファイルとして格納されます。 このファイルがある場合は、データベースへのラウンドトリップは必要ありません。代わりにこのファイルが使用されます。 便利な File オブジェクトと Stream オブジェクトを使った例を以下に示します。

 Dim DataFile As File Dim FileData As String If DataFile.Exists(CurDir() & "\" & FileName) Then    Dim FileReader As New StreamReader(CurDir() & "\" & FileName)    FileData = FileReader.ReadToEnd()    FileReader.Close() Else    Dim FileWriter As New StreamWriter(CurDir() & "\" & FileName)    FileWriter.WriteLine(AnswersSchema)    FileWriter.Close() End If  

上のコードを 'Open FileName For Output As #1' と比較してみてください。


プロジェクトの種類

Microsoft® Visual Studio® .NET では、さまざまな種類のプロジェクトを選択できます。 Visual Basic 分散アプリケーション プロジェクトを選択すると、複数のソース コード フレームワーク プロジェクトが n 層形式で生成されます。 今回は、生成される WebFacadeBusinessFacade を 1 つの Facade インターフェイスへと結合することにしました。 さらに、BusinessRules クラスと DataAccess クラスも使用しています。 すべてのクラスは、Jaggle.Questionnaire 名前空間に含まれています。



These are our most popular posts:

questionnaire

Questionnaire. The questionnaire module allows you to construct questionnaires (surveys) using a variety of question ... データベースモジュールでは教師および学生 があらゆるトピックに関するレコードエントリのバンクを構築、表示および検索することが できます。 ... レッスンでは楽しくフレキシブルな方法で学習コンテンツを提供します。 read more

調査レポート 企業で働く仕事力とは? 労政時報クラブアンケートに見る ...

例: 旅券なしでも本人確認が可能となるように/直接公館を訪問する以外の方法を用意/ 一度の登録で何回でも選挙が可能なように) .... 的合意を土台にした持続可能な対北 朝鮮政策推進、⑩周辺4強外交関係強化および東北アジア平和協力体制構築である。 read more

投票2012 政党アンケート

或いは学士入学の選抜方法のように一定期間行動パターンや言動を観察して評価する のもよい。 1. 3. 教養教育の成果が明示されていないこと。 明示できるようなシステムの 構築。 1. 3. 目的と教養教育が全く解離している。講義で観察力・洞察力,倫理観,判断 ... read more

SQS: Shared Questionnaire System プロジェクト日本語トップページ ...

Shared Questionnaire System(SQS)は、直観的なGUIを備えた、統合化された光学式 マーク読み取り(OMR)フォーム処理系です。XML標準に基づいて調査についての知識 共有を行う社会的基盤の構築を目的としています。 SQSが対象とするユーザ像… read more

0 件のコメント:

コメントを投稿