显示多对多关系(嵌套ListViews?)

时间:2009-09-17 08:39:54

标签: c# asp.net listview many-to-many

我很欣赏这可能是一个相当简单的问题 - 但我遇到了很多麻烦(作为一个狡猾的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 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复杂支持多对多关系而很重要)。

2 个答案:

答案 0 :(得分:4)

您可以使用嵌套转发器。下面的示例调用代码隐藏文件中的辅助方法,该方法返回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>

                    

这可能不是最好的解决方案,但它是一个有效的解决方案,所以我希望它可以帮助你

答案 1 :(得分:2)

很简单,您可以在“学生”课程中添加几个新属性,如下所示(在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”属性删除了对子转发器的需求。

顺便说一句,我强烈建议以单数形式命名表格(即在1行代表之后命名)。此外,还有一个很好的例子,即从StudentCourses表中删除标识列,并将其替换为Student_Id和Course_Id之间的复合键。

希望这有帮助。