次のStudentGroup
クラスがあります。
public class StudentGroup
{
[Key]
public int Id { get; set; }
//the set of peers who will review the work of the StudentGroup
[ForeignKey("PeerReviewGroupId")]
public PeerReviewGroup PeerReviewGroup { get; set; }
public int? PeerReviewGroupId { get; set; }
public IEnumerable<GroupMembership> GroupMemberships { get; set; }
}
このクラスから派生したPeerReviewGroup
には、2つの新しいプロパティがあります。
public class PeerReviewGroup: StudentGroup
{
[ForeignKey("StudentToReview")]
public ApplicationUser StudentToReview { get; set; }
public string StudentToReviewId { get; set; }
[ForeignKey("StudentGroupToReview")]
public StudentGroup StudentGroupToReview { get; set; }
public string StudentGroupToReviewId { get; set; }
}
PeerReviewGroup
は、個人(つまりStudentToReview
)または別のグループ(つまりStudentrGoup
)に割り当てることができます。したがって、これらの値のいずれかはnull
である必要があります。
代わりに、2つのクラスを駆動できます。
public class PeerReviewGroupForIndividuals: StudentGroup
{
[ForeignKey("StudentToReview")]
public ApplicationUser StudentToReview { get; set; }
public string StudentToReviewId { get; set; }
}
public class PeerReviewGroupForGroups: StudentGroup
{
[ForeignKey("StudentGroupToReview")]
public StudentGroup StudentGroupToReview { get; set; }
public string StudentGroupToReviewId { get; set; }
}
これが望ましいのか、そうでないのか、どちらのアプローチがベストプラクティスなのでしょうか。 2つのクラスを派生させると状況が複雑になると思います。助言がありますか?
私はあなたがmay問題を過度に複雑にしていると感じています。
次のアプローチが機能しないのはなぜですか?
public class StudentGroup
{
[Key]
public int Id {get; set;}
//the students who comprise the group
//the list can contain 1 to n users
public List<ApplicationUser> Members
}
public class PeerReviewSession
{
//this is the group of students who are performing the review
[ForeignKey("GroupReviewing")]
public StudentGroup GroupReviewing {get; set;}
//this is the group of students who are being reviewed
[ForeignKey("GroupReviewed")]
public StudentGroup GroupReviewed {get; set;}
}
シナリオ全体がわからないため、ここにいくつかの要素が欠けている可能性があります。ただし、基本的な前提がコメントで提案したとおりである場合:
「2つのグループの学生がいて、1つのグループが他のグループをレビューできる」
次に、これが本当に必要なすべてです。
PeerReviewGroup
は、個人(つまりStudentToReview
)または別のグループ(つまりStudentGroup
)に割り当てることができます。したがって、これらの値のいずれかはnull
である必要があります。代わりに、2つのクラスを運転できます
額面では、あなたの解釈は正しいです。同時に両方のプロパティが必要になることはないため、同じエンティティ/テーブルにそれらを配置する目的はありません。
ただし、特定の(既存の)ピアレビューグループを今日の学生と明日の学生グループに割り当てることができる可能性は十分にあるようです。エンティティを分割した場合は、生徒またはグループに割り当てられるように切り替わるたびに、ピアレビューグループを再作成する必要があります。
あなたのアプリケーションについて、その呼び出しを行うのに十分な知識がありません。
エンティティの継承は、物事を正気に保つのに役立つ非常に強力なツールです。しかし、いつものように、継承を過剰に適用すると、狂気につながります。
代替案
これに対するもう1つのアプローチは、査読グループを派生させずに、学生と学生グループの間に基本クラスを提供することです。以下に沿ったもの:
public abstract class PeerReviewSubject
{
public string Id { get; set; }
}
public class Student : PeerReviewSubject { }
public class StudentGroup : PeerReviewSubject { }
public class PeerReviewGroup : StudentGroup
{
[ForeignKey("Subject")]
public PeerReviewSubject Subject { get; set; }
public string SubjectId { get; set; }
}
あなたが使用しているstring
IDは好きではありませんが、それは別の戦いです。
これにより同じ結果が得られますが、新しいピアレビュー可能なエンティティタイプがドメインに追加されるたびにPeerReviewGroup
を拡張し続ける必要はありません。代わりに、すべての新しいピアレビュー可能なエンティティタイプは単にPeerReviewSubject
から派生するため、ピアレビューグループに割り当てることができます。
例ではPeerReviewSubject
を抽象化しました。これは必須ではありませんが、それ以上の派生なしでベアボーンPeerReviewSubject
オブジェクトを作成したくない場合は、この方法が適しています。
この質問に答えるには、PeerReviewGroup
のライフサイクルについて考える必要があります。
両方の質問に対する答えが「はい」の場合、2つのクラスを作成することを検討できます。しかし、これは必ずしもそうすべきだという意味ではありません。
より基本的な質問は、PeerReviewGroupforIndividuals
IS-Aが実際に特定のPeerReviewGroup
であるかどうかであり、他とは非常に異なります(継承)または、それが単なるPeerReviewGroup
である場合は、HAS-A異なるSubject
を調査(構成)するだけです。結局のところ、個人をレビューしているピアレビューグループほど、グループをレビューしているピアレビューに近いものはありません。同じグループで両方を行うこともできます。
2つの選択肢の境界は、あいまいになる可能性があります。疑問がある場合:
優先 継承よりも構成