質問

簡単に説明できないシナリオがありますが、それは非常に一般的な問題であると確信しています。問題を説明するために最善を尽くします。

調査を作成できる調査アプリケーションがあるとします。各調査には独自の構造があります(質問を含む、質問はグループ化され、順序付けられます)。これらの調査は管理者によって管理され、マスター調査テンプレートと呼ばれます。 これで、ユーザーはこれらのマスター調査のいずれかを選択し、いくつかのカスタマイズを行い、一部の人に対して調査を実施できます。

したがって、基本的には、すべて同じ構造(コレクション、プロパティなど)を共有する調査がありますが、データは異なる場合があります。

DBのモデリング方法

私の考えは、すべてを1つのテーブルに格納し、テンプレートと実施済みテンプレートを分離する列を作成することです。

tbl_Survey (id, name, conducted_on)

クラスをどのようにモデル化しますか?

私の考えは次のとおりです。

Survey {
  Name
  Questions
}

ConductedSurvey : Survey {
  //gets the master according to the name
  GetMaster()
}

重要:調査には、他のクラスとの多くの関係があります。サブクラス化する場合。すべてをサブクラス化する必要があります(各オブジェクトのマスターからデータをコピーするため)?

役に立ちましたか?

解決

  

つまり、基本的にはすべて同じ構造(コレクション、プロパティなど)を共有する調査がありますが、データは異なる場合があります。...私の考えは、すべてを1つのテーブルに格納し、テンプレートと実施されたもの。

さて、あなたが話しているのはプロトタイプです。 「テンプレート」調査はプロトタイプです。明らかに、プロトタイプがプロトタイプに基づいたインスタンスとまったく同じ構造を持っている場合、同じ構造に対してまったく異なるテーブルを作成するのは愚かで無駄になります。両方のセットでミラーリングする必要があります。

実施した調査からプロトタイプ/テンプレートを区別するために列を追加しますか?いいえ、おそらくそうではありません。代わりに、ルート調査テーブルと1対1の関係を持つ別のテーブルを追加します。この表では、プロトタイプと非プロトタイプを区別するメタデータを少し追加します。

次の3つの理由によります。1)合理的なシステムでは、プロトタイプは総調査の少数派になります。 2)私はしばしばすべてのプロトタイプをリストしたいと思います。 「新しい調査ウィザードの作成」新しい調査の基礎となるプロトタイプの選択肢がリストされています。 3)追加のデータを少し保持する:

create table survey_prototype (
    id int not null primary key,
    survey_id references survey(id) -- the regular survey table
    wizard_description varchar(80)
    . . . .
);

今、調査にも説明があると思いますが、プロトタイプの説明は、「これはユーザーが参照する説明です」のようなものです。そのwizard_descriptionは、「プロトタイプの政治投票」のようなものです。

今、プロトタイプ/テンプレートのルックアップは実施された調査を返す可能性がないため(実施された調査はsurvey_prototypeに参加しないため)、getMasterは(概念的に、おそらくORMを使用する)次のようになります:

ConductedSurvey : Survey {
  //gets the master according to the name
  GetMaster() { "select * from survey_prototype join survey..."
}
  

重要:調査には、他のクラスとの多くの関係があります。サブクラス化する場合。すべてをサブクラス化する必要があります(各オブジェクトのマスターからデータをコピーするため)?

あなたは正しいです。ORMから取得したプロトタイプについては、プロトタイプを上書きするのではなく、ディープコピーして新しい調査を保存する必要があります。とにかくディープコピーを行う必要があるため、ディープコピーでは、プロトタイプが使用する基本クラスを作成する代わりに、サブクラスコピーを作成できます。

もちろん、階層の各レベルでその決定を行う必要があります。ディープコピー変換用の各変換ポリシーを1つのクラスにカプセル化すると便利です。タイプの(ベース)クラスごとに1つのオーバーロードされた visit 関数があるので、Visitor Patternはこれを行います:(少なくとも) visitSurvey visitQuestion visitAnswer

ツリー(調査に根ざし、子供の質問と孫の回答、つまり複合パターン)を扱うため、コピー/トランスフォーマで訪問者パターンを使用することをお勧めします。クラスは比較的安定しているため、ビジターはうまく機能します。そして、それはあなたが複数の異なる具体的な訪問者を持つことを可能にし、それぞれのタイプの変換に対応します(そして、調査を表示または採点する時が来たら、あなたもその訪問者を書くことができます-その機能をほとんど"訪問者パターンを設定したら無料で」)。

データベースのサブクラス化を処理するには、このための一般的なnhibernateパターンのいずれかを使用できます。そうすれば、一度訪問して変換すると、nhibernateによって自動的にデータベースに保存できる新しいプロトタイプではない調査ツリーが作成されます。

要約すると:survey_prototypeテーブル、プロトタイプを取得、nhibernateはsurvey_prototypeでルートを要求するとツリー全体を取得し、コピーされたルートを返すディープコピートランスフォーマーでそのツリーにアクセスし、ユーザーがその上に書き込みます、コピーしたルートを保存し、nhibernateにツリーのすべてのノードを再帰的に保存させます。ユーザーがする必要があるとき

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top