选课页面来了!!本质上还是对数据库进行一些增删改查。
一、 选课列表页面框架设计
- 建立CourseSelection.aspx页面,和前面的页面类似的,先把上下左侧页面设置为默认值,只对右侧页面进行操作;
- 与前面写过的消息展示页面非常类似,控件上是SQLDataSource和Repeater,具体引用上是在repeater中HeaderTemplate中添加标题,ItemTemplate中使用“<%# EVAL("lesson_ID")%>”的形式引用;
- 区别在于需要给每行添加一个选课按钮,点击这个按钮可以实现功能。为了对齐,给HeaderTemplate增加一个空标签,用于对应ItemTemplate的选课按钮。为了实现选课,我们添加一个CommandArgument='<%# Eval("lesson_ID") %>'>属性,代码如下:
<asp:Content ID="Content5" ContentPlaceHolderID="content" runat="server"> <style> .table-container { display: flex; justify-content: center; margin-bottom: 40px; margin-left:30px; margin-right:30px; } table { width: 100%; } .my_line{ text-align: left; vertical-align: middle; font-size: 24px; } .my_title{ text-align:center; } </style> <h1 class="my_title">全校课表</h1> <div class="table-container"> <table> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:dbConnstr %>" SelectCommand="SELECT * FROM [lesson] ORDER BY [lesson_weekday], [lesson_time]"> </asp:SqlDataSource> <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1"> <HeaderTemplate> <tr> <th class ="my_line">课程编号</th> <th class ="my_line">课程名称</th> <th class ="my_line">开设专业</th> <th class ="my_line">课程时间</th> <th class ="my_line">开设时刻</th> <th class ="my_line"></th> </tr> </HeaderTemplate> <ItemTemplate> <tr> <td class ="my"><%#Eval("lesson_ID") %></td> <td class ="my"><%#Eval("lesson_name") %></td> <td class ="my"><%#Eval("lesson_major") %></td> <td class ="my"><%#Eval("lesson_weekday") %></td> <td class ="my"><%#Eval("lesson_time") %></td> <td class ="my"> <asp:LinkButton ID="btnSelectCourse" runat="server" Text="选课" OnClick="btnSelectCourse_Click" CommandArgument='<%# Eval("lesson_ID") %>'></asp:LinkButton> </td> </tr> </ItemTemplate> </asp:Repeater> </table> </div> </asp:Content>
二、 sql语句
前面进行了页面的设计,没有实现具体的功能,下面来实现具体的功能。其中比较麻烦的一件事情就是sql语句的设计,所以进行单独的设计。
与这个功能有关的一共有三张表:user_info(ID, Password), lesson(lesson_ID, lesson_name, lesson_major, lesson_weekday, lesson_time), take_course(ID, lesson_ID)。
选课相当于向take_course表中插入一条新的数据,sql语句需要筛选出可以进行选课的情况进行插入。具体来说,可以插入的情况应该满足以下条件:目前没有被选中;在这个课上课的同时没有已经选了的其他课程。满足这两个条件即可插入。
IF NOT EXISTS (
-- 判断时间是否冲突
SELECT 1
FROM take_course tl
INNER JOIN lesson l ON tl.lesson_ID = l.lesson_ID
WHERE tl.ID = @studentID
AND (
l.lesson_time = (
SELECT lesson_time
FROM lesson
WHERE lesson_ID = @lessonID
)
AND l.lesson_weekday = (
SELECT lesson_weekday
FROM lesson
WHERE lesson_ID = @lessonID
)
)
)
BEGIN
-- 检查学生是否已选该课程
IF NOT EXISTS (
SELECT 1
FROM take_course
WHERE ID = @studentID
AND lesson_ID = @lessonID
)
BEGIN
-- 可以选课,将选课信息插入 take_course 表
INSERT INTO take_course (ID, lesson_ID)
VALUES(@studentID, @lessonID);
--在此处添加选课成功的逻辑
SELECT '选课成功' AS Result;
END
END
三、 实现选课功能
前期准备完毕,开始实现功能!
- 连接数据库,
- 传递参数,
- 传输语句,输出结果
//创建公共变量connStr public string connStr = ConfigurationManager.ConnectionStrings["dbConnstr"].ConnectionString; protected void btnSelectCourse_Click(object sender, EventArgs e) { // 获取点击按钮所在的 Repeater 项 //RepeaterItem item = (sender as LinkButton).NamingContainer as RepeaterItem; // 获取课程编号 LinkButton btnSelectCourse = (LinkButton)sender; string lessonID = btnSelectCourse.CommandArgument; string studentID = Session["ID"].ToString(); // 执行选课逻辑,可以在此处编写代码 //第一步:建立连接对象conn using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); // 检查学生是否已选其他同一时间段的课程 string checkOtherCoursesQuery = @"IF NOT EXISTS ( SELECT 1 FROM take_course tl INNER JOIN lesson l ON tl.lesson_ID = l.lesson_ID WHERE tl.ID = @studentID AND ( l.lesson_time = ( SELECT lesson_time FROM lesson WHERE lesson_ID = @lessonID ) AND l.lesson_weekday = ( SELECT lesson_weekday FROM lesson WHERE lesson_ID = @lessonID ) ) ) BEGIN -- 检查学生是否已选该课程 IF NOT EXISTS ( SELECT 1 FROM take_course WHERE ID = @studentID AND lesson_ID = @lessonID ) BEGIN -- 可以选课,将选课信息插入 take_course 表 INSERT INTO take_course (ID, lesson_ID) VALUES (@studentID, @lessonID); -- 在此处添加选课成功的逻辑 SELECT '选课成功' AS Result; END ELSE BEGIN -- 返回结果标识符为 '学生已选该课程' SELECT '学生已选该课程' AS Result; END END"; using (SqlCommand cmd = new SqlCommand(checkOtherCoursesQuery, conn)) { //传递sql语句需要的两个参数,@studentID和@lessonID cmd.Parameters.AddWithValue("@studentID", studentID); cmd.Parameters.AddWithValue("@lessonID", lessonID); int rowsAffected = cmd.ExecuteNonQuery(); if (rowsAffected > 0) { // 选课成功逻辑 Response.Write("<script>alert('选课成功!');</script>"); } else { // 插入数据失败的逻辑 Response.Write("<script>alert('选课失败!');</script>"); } } conn.Close(); } }
四、 遇到的问题
-
列表信息展示在应有的框之外:解决方法:添加一个<table></table>将SqlDataSource开始全部包括进去。
- 运行后遇到如下报错:最后发现,这个错误并不是reader本身的错误,是sql语句存在错误,我当时的错误是使用了natural join和inner join,后来发现sql server里面不能使用natural join和inner join。我觉得发现和解决这个问题比较好的方式是先在sql server里面实现指令。