Отображение отношений «многие ко многим» (вложенные списочные представления?) - PullRequest
4 голосов
/ 17 сентября 2009

Я понимаю, что это может быть довольно простой вопрос - но у меня возникли некоторые проблемы (как начинающий разработчик ASP.NET). Я получил несколько идей от SO и Google без удачи, и я думаю, что начинаю задумываться над этим, кажется, что это такой стандартный сценарий, что я считаю, что упускаю что-то очевидное.

У меня есть, например, три стандартных примера таблиц - обратите внимание на отношение «многие ко многим».

Students
- student_id
- forename
- surname

Courses
- course_id
- course_name

StudentCourses
- studentcourse_id
- course_id
- student_id

Я бы хотел отобразить их в моем веб-приложении ASP.NET 3.5 так, чтобы они выглядели примерно так (последний столбец - кнопка, позволяющая им редактировать информацию об ученике):

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 до моего текущего фаворита, ListView, который шел с 3.5. Я использую LINQ to SQL в качестве слоя данных (в случае, если это важно из-за сложной поддержки LINQ отношений «многие ко многим»).

Ответы [ 2 ]

4 голосов
/ 17 сентября 2009

Вы можете использовать вложенные повторители. В приведенном ниже примере в коде файла вызывается вторичный метод, который возвращает список. Вы можете получить доступ ко всей информации о курсе из этого. Я мог бы заставить его работать с методом из класса репозитория, поэтому использовал код ниже, чтобы обойти это:

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>

Возможно, это не лучшее решение, но это рабочее решение, поэтому я надеюсь, что оно вам поможет

2 голосов
/ 17 сентября 2009

Проще говоря, вы можете добавить пару новых свойств в ваш класс "Student" следующим образом (в 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 );
    }  
}

Теперь, когда вам нужен только один ретранслятор (привязанный к вашей коллекции учащихся), поскольку потребность в суб-репитере устраняется свойством «CoursesDescription» в классе Student.

Кроме того, я бы настоятельно рекомендовал именовать ваши таблицы в единственном числе (т.е. вы называете их после того, что представляет 1 строка). Кроме того, есть веские основания для удаления столбца идентификаторов из таблицы StudentCourses и замены его составным ключом для Student_Id и Course_Id.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...