2009-03-27 4 views
5

Personが異なるプロジェクトのメンバーになり、異なるプロジェクトロール(「プロジェクトリード」や「プロジェクトメンバー」など)に存在するProject、ProjectRole、Personの3つのエンティティがある場合関係?データベースでDomain Driven Designを使用してどのようにロール/リレーションシップをモデル化していますか?

、私は現在、次のtablers持っている:プロジェクト、人、PKとFKの関係などProjectRoleIdとしてPERSONID & PROJECTIDとProjectRole Project_Personを。

私が思いつくすべてのドメインモデルは、いくつかの "DDD"ルールを破るように見えるので、私は本当にここにいなくなっています。この問題の「基準」はありますか?

私はStreamlined Object Modelingを見ていますが、ProjectとProjectMemberのようなものがありますが、ProjectのAddProjectMember()はProjectMember.AddProject()を呼び出します。したがって、ProjectにはProjectMembersのリストがあり、各ProjectMemberにはProjectへの参照があります。私にちょっと混乱しているように見えます。

更新

この主題についての詳細を読んだ後、私は次のことをしようとします。自分のドメイン内の特定のロールタイプである異なる役割、またはより良い、モデルの関係があります。たとえば、ProjectMemberは、Personがプロジェクト内で果たす関係について何かを教えてくれる別個の役割です。それには、再生される役割の詳細を示すProjectMembershipTypeが含まれています。私は人がプロジェクトの中で役割を演じなければならないことを確かに知っているので、私はその関係をモデル化します。

ProjectMembershipTypesを作成して変更することができます。これらは、「プロジェクトリーダー」、「開発者」、「外部アドバイザー」など、さまざまなものがあります。

人はプロジェクト内で多くの役割を持つことができ、これらの役割は特定の日付に開始および終了できます。そのような関係は、ProjectMemberクラスによってモデル化されます。

public class ProjectMember : IRole 
{ 
    public virtual int ProjectMemberId { get; set; } 
    public virtual ProjectMembershipType ProjectMembershipType { get; set; } 

    public virtual Person Person { get; set; } 
    public virtual Project Project { get; set; } 
    public virtual DateTime From { get; set; } 
    public virtual DateTime Thru { get; set; } 
    // etc... 
} 

ProjectMembershipType:ie。 「プロジェクトマネージャ」、「開発」、「顧問」

public class ProjectMembershipType : IRoleType 
{ 
    public virtual int ProjectMembershipTypeId { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 

    // etc... 
} 

答えて

1

多対多の関係をモデリングしています。プロジェクトには多くの人が作業でき、複数のプロジェクトで作業することができます。

あなたはPerson < - > Projectから双方向リンクとして機能するだけでなく、そのプロジェクトのRoleTypeを記入してそのPersonの開始/終了を記録するプロジェクトロールとしてリレーションをモデリングしています。

これらのFKのために、私たちはデータベースからPerson、Project Roleを通じてグラフに従うことができますが、プロジェクトへ:

select a.person_id, b.project_role_id, c.project_id 
from person a join project_role b on (a.id = b.person_id) 
join project c on (b.project_id = c.id) 
where a.person_id = ? 

それとも我々はプロジェクトから、他の方向に従うことができます:

select a.person_id, b.project_role_id, c.project_id 
from person a join project_role b on (a.id = b.person_id) 
join project c on (b.project_id = c.id) 
where c.project_id = ? 

理想的には、C#コードで同じことを行うことができるようにしたいと思います。ですから、Personにはリストがあり、Projectにはリストがあり、ProjectRoleにはPersonとProjectが参照されています。我々はProject::addPerson(Person&)は、フォームの便利な方法であると判断しない限り、

はい、Project::addPerson(Person&)は本当に、Project::addProjectRole(ProjectRole&)次のようになります。

void Project::addPerson(Person& p) { 
    this.addProjectRole(new ProjectRole(p, &this, RoleType::UNASSIGNED) ; 
} 

A ProjectRoleがリストを持っていないが、それが持っている、人への参照をし、プロジェクトへの参照。また、値として、開始日、終了日、RoleType(列挙型、または列挙型の値を模倣するクラスインスタンス、つまり列挙型ごとにオブジェクトが1つしかありません)があります。ステートレス、不変、冪等であり、多くのProjectRolesの中で共有可能です)。

これは、データベースからPersonを取得すると、データベース全体がコード内のオブジェクトグラフに反映されるはずではありません。使用時にのみ取得する遅延プロキシは、そのことから私たちを救うことができます。それで、私たちが現在自分のロールではなく、自分のロールではないならば、私たちは人を取得することができます(NHibernateでは、これは多かれ少なかれシームレスにやります)。

基本的に私は次のように思っています:

1)これは多対多関係を表す標準的な方法です。 2)追加のデータを持つことは関係の標準です(どんな種類のとき) と; 3)あなたは正しいアイデアを得ており、ここでフィードバックを得ているだけで良心的です。

0

あなたは人がプロジェクトに持っている役割と役割の「説明」混乱ではありませんか? 「RoleDescription」の概念(言い換えれば役割クラス)と、実際の人物を参照する「RoleInstance」オブジェクトをプロジェクトに追加すると役立ちます。

+0

私は考えていませんが、あなたは何を意味するのかよく分かりません – kitsune

+0

私はリレーショナルデータベースの時代からデートしていますが、あまりにも多くのOODを食べました...私は 'Second Solution'ジェイミーの答え。 – xtofl

0

あなたが持っているものは、追加のデータである多対多の関係です。私たちのケースでは、人がプロジェクトに複数の役割を果たすかもしれないという点を除いて、私たちは同様の構造を持っていました。私は同じ質問に苦労しました。一つの解決策は、人を拡張し、役割のプロパティを追加ProjectPersonクラスを作成することです:

public class ProjectPerson : Person 
{ 
    public string Role { get; set; } 
} 

プロジェクトクラスは今ProjectPersonのコレクションを持っていますが、それはしても意味がありませんので、Personクラスは、プロジェクトのコレクションを持っていますロールを追加するためにProjectクラスを拡張します。人の視点からプロジェクトの役割を見つけるためには、いくつかの追加作業(ProjectPersonコレクションのPersonを参照)を行う必要があります。

2番目の解決方法は、追加データを使用して多対多の関係を処理する標準的な方法です。 ProjectRoleクラスを作成し、それをProjectとPersonから2つの1対多の関係の多くの側面としてモデル化します。つまり、ProjectとPersonの両方にそれぞれProjectRoleのコレクションがあります。

ソリューションの選択において、データアクセス戦略がモデルをどれだけうまくサポートするかを検討することが重要です。コレクションの読み込みで、コレクション内の各オブジェクトのデータベースへの1回以上のトリップが必要なシナリオを回避したいとします。ここで

+0

私は、「BillablePerson」、「InternshipPerson」、「TerriblePerson」という、まったく同じ「本物の」人物を指すことになるので、「ProjectPerson」クラスに対してアドバイスします。私は継承の解決策の代わりに関係を持っている。 – xtofl

+0

私はあなたの議論を理解していません:提案されたソリューションは、Personの追加の拡張をどのように作成するでしょうか? ProjectPersonは、プロジェクトのコンテキスト内の役割のPersonです。データベースの用語では、personテーブルを多対多のリンクテーブルに結合することによって検索されます。 –

3

は、私はそれを処理する方法をです:

class Person 
{ 
    string Name { get; set; } 
    IList<Role> Roles { get; private set; } 
} 

class Role 
{ 
    string Name { get; set; } 
    string Description { get; set; } 
    IList<Person> Members { get; private set; } 
} 

class Project 
{ 
    string Name { get; set; } 
    string Description { get; set; } 
    IList<ProjectMember> Members { get; private set; } 
} 

class ProjectMember 
{ 
    Project Project { get; private set; } 
    Person Person { get; set; } 
    Role Role { get; set; } 
} 

ProjectMemberクラスは一緒にすべてをもたらします。このモデルを使用すると、同じPersonを異なるロール(プロジェクトAの開発者、ProjectBのTesterなど)を持つ異なるプロジェクトに割り当てる柔軟性が得られます。

ロール特有のクラスを作成しないでください。そのレッスンは既に学習されています。

  1. 実行
  2. エンティティを作成するために、ライブラリのアイコンをダブルクリックし、「RolesRelationshipsSample.exe \ ビン\デバッグを」:

    私は、これは(それはあまりにも関係が含まれる)実証するsample appを作成しました

  3. ドラッグ/適切な関係

は、コードでアイテム課金気軽に割り当てるためにそれらをドロップします。あなたはそれが有用であることを願っています。

+0

ありがとう!私はあなたのような同様の方向に行きました、更新された質問をチェックしてください。 – kitsune

+0

@Vijay Patelなぜロール固有のクラスを作成しないのですか?各ロールがプロジェクトで異なるアクションを実行できる場合はどうなりますか? – richard

+0

@リチャード:私の例から、 "ロール"のサブクラスは問題ではありません。私は、以下のJamie井戸のシナリオについてもっと詳しく言及していたと思います。http://stackoverflow.com/a/689618/80369 –

0

プロジェクトエンティティとプロジェクトメンバの2つの主要なエンティティがあるようです。 プロジェクトメンバーには、 'Member Role'と 'Member Name'という属性があります。これらの属性のいずれかは、ドメイン、すなわち検索の便宜と検索の両方のためにルックアップテーブルで管理できる値のセットに属しています。特定の役割/職務を遂行するすべてのプロジェクトメンバーに関する情報が必要とされることが前提です。

注。ルックアップテーブルにエントリを追加できますが、通常はエントリの値が変更されません。ルックアップ・テーブルから値が選択されると、それは所有テーブルの永続的なフィクスチャ - この場合はプロジェクト・メンバー・テーブルとみなされます。

上記のように、ルックアップテーブルとして利便性以外のビジネスで「Person」エンティティまたはテーブルが表示されることは期待しません。 HR部門は、給与計算などで必要とされる特定の情報を持つ従業員のリストを保持しますが、ビジネスが知る必要のある人々は根本的なものではありません。エンティティを識別するためのビジネスプロセスを見つけます。エンティティを構成しません。

関連する問題