Visualizzazione delle relazioni Many-to-Many (Nested ListViews?)
-
08-07-2019 - |
Domanda
Apprezzo che questa sia una domanda abbastanza semplice, ma sto avendo un bel po 'di problemi (come sviluppatore ASP.NET in erba). Ho avuto un certo numero di idee da SO e Google senza fortuna e penso che sto iniziando a pensarci troppo, sembra uno scenario così standard che credo che mi manchi qualcosa di ovvio.
Ho, ad esempio, tre tabelle di esempio standard: nota la relazione Many-to-Many.
Students
- student_id
- forename
- surname
Courses
- course_id
- course_name
StudentCourses
- studentcourse_id
- course_id
- student_id
Vorrei mostrarli sulla mia applicazione Web ASP.NET 3.5 in un modo simile a (l'ultima colonna è un pulsante per consentire loro di modificare le informazioni dello studente):
Students:
# Name Courses Actions
1 Joe Bloggs Maths, English [Manage]
2 Arthur Sleep English [Manage]
3 Andy Mann Maths, German, French [Manage]
I " corsi " colonna è un elenco dei corsi a cui lo studente è attualmente iscritto. Potrebbe essere vuoto (non ancora registrato) o contenere un elenco (delimitato da virgole o un elenco HTML non ordinato standard, non sono prezioso) dei corsi attualmente iscritti. Non si tratterebbe di un elenco enorme in quanto uno studente può iscriversi a una manciata di corsi alla volta.
Ho provato una serie di soluzioni, che vanno da asp: Repeater's al mio preferito attuale, il ListView fornito con 3.5. Sto usando LINQ to SQL come livello di dati (nel caso sia importante a causa del complicato supporto di LINQ per le relazioni Many-to-Many).
Soluzione
Molto semplicemente, potresti aggiungere un paio di nuove proprietà al tuo " Studente " classe come segue (in 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 );
}
}
Ora, quando avrai bisogno di un solo ripetitore (associato alla tua raccolta di studenti), poiché la necessità del ripetitore secondario viene rimossa da " CoursesDescription " proprietà nella classe Student.
A parte, consiglierei vivamente di nominare i tuoi tavoli al singolare (ovvero, chiamarli come quello che rappresenta 1 riga). Inoltre, esiste un valido motivo per rimuovere la colonna Identity dalla tabella StudentCourses e sostituirla con una chiave composita in Student_Id e Course_Id.
Spero che questo aiuti.
Altri suggerimenti
Puoi usare ripetitori nidificati. L'esempio seguente chiama un metodo secondario nel codice dietro il file che restituisce un elenco. Puoi accedere a tutte le informazioni sul corso da questo. Potrei farlo funzionare con un metodo da una classe di repository, quindi ho usato il codice qui sotto per aggirare questo:
protected List<tblStudentCourses> GetStudentCoursesByStudentID(int id)
{
return studentRepository.GetStudentCoursesByStudentID(id).ToList();
}
Ecco l'esempio completo:
<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>
Questa potrebbe non essere la soluzione migliore ma è una soluzione funzionante, quindi spero che ti aiuti