多対多の関係の表示(ネストされたリストビュー?)
-
08-07-2019 - |
質問
これは非常に単純な質問かもしれないことを感謝しています-しかし、私はかなりの問題を抱えています(最初のASP.NET開発者として)。 SOとGoogleから運よく多くのアイデアを獲得しましたが、私はこれを過剰に考え始めていると思います。それは標準的なシナリオのようで、明らかな何かを見逃していると思います。
たとえば、3つの標準的なサンプルテーブルがあります-多対多の関係に注意してください。
Students
- student_id
- forename
- surname
Courses
- course_id
- course_name
StudentCourses
- studentcourse_id
- course_id
- student_id
次のような方法でASP.NET 3.5 Webアプリケーションにこれらを表示したいです(最後の列は生徒情報を編集できるボタンです):
Students:
# Name Courses Actions
1 Joe Bloggs Maths, English [Manage]
2 Arthur Sleep English [Manage]
3 Andy Mann Maths, German, French [Manage]
"コース"列は、学生が現在登録しているコースのリストです。これは空(まだ登録されていない)か、現在登録されているコースのリスト(コンマ区切りまたは標準の順序付けられていないHTMLリスト、私は重要ではない)を含むことができます。学生は一度に少数のコースにしか登録できないため、これは大規模なリストではありません。
asp:Repeaterから現在のお気に入りである3.5に付属のListViewまで、さまざまなソリューションを試しました。データレイヤーとしてLINQ to SQLを使用しています(多対多リレーションシップのLINQの複雑なサポートのために重要な場合)。
解決
簡単に言うと、「学生」にいくつかの新しいプロパティを追加できます。次のようなクラス(C#):
public IEnumerable<Course> Courses
{
get { return CourseRepository.GetCoursesByStudentId(this.Student_Id); }
}
//Aggregate course names into a comma-separated list
public string CoursesDescription
{
get
{
if (!Courses.Any())
return "Not enrolled in any courses";
return Courses.Aggregate(string.Empty, (currentOutput, c) =>
(!String.IsNullOrEmpty(currentOutput)) ?
string.Format("{0}, {1}", currentOutput, c.Course_Name) : c.Course_Name );
}
}
サブリピータの必要性が&quot; CoursesDescription&quot;によって削除されるため、リピータが1つだけ必要になります(学生コレクションにバインドされています)。 Studentクラスのプロパティ。
余談ですが、テーブルに単一の名前を付けることを強くお勧めします(つまり、1行が表すものにちなんで名前を付ける)。また、StudentCoursesテーブルからID列を削除し、Student_IdとCourse_Idの複合キーで置き換えるという強力なケースがあります。
これがお役に立てば幸いです。
他のヒント
ネストされたリピーターを使用できます。以下の例は、Listを返すコードビハインドファイル内のセカンダリメソッドを呼び出します。これからすべてのコース情報にアクセスできます。リポジトリクラスのメソッドで動作させることができたので、以下のコードを使用してこれを回避しました。
protected List<tblStudentCourses> GetStudentCoursesByStudentID(int id)
{
return studentRepository.GetStudentCoursesByStudentID(id).ToList();
}
完全な例を次に示します。
<asp:Repeater ID="parentRepeater" runat="server" DataSourceID="myDataSource">
<HeaderTemplate>
Header HTML
</HeaderTemplate>
<ItemTemplate>
<asp:Repeater ID="availabilityRepeater" runat="server" DataSource='<%#GetStudentCoursesByStudentID(Convert.ToInt32(Eval("studentCourseID"))) %>'>
<ItemTemplate>
<%# Eval("tblStudentCourses.courseName") %><br />
</ItemTemplate>
</asp:Repeater>
Student Name example: <%#Eval("studentName")%>
</ItemTemplate>
<FooterTemplate>
Footer HTML
</FooterTemplate>
これは最善の解決策ではないかもしれませんが、実用的な解決策なので、あなたに役立つことを願っています