为微软ContosoUniversity例子加上学生自选课程计划
把ContosoUniversity例子过了一遍,好象还是有很多东西未能理解,决定自己随便加个功能看可以自己完成不....
从github的例子中clone下来ContosoUniversity项目,使用CodeFirst进行迁移后就可以得到一个正常运作的例子。
增加的课程计划 StudentCoursePlan.cs
public partial class StudentCoursePlan
{
public int Id { get; set; }
public int CourseId { get; set; }
public int StudentId { get; set; }
public Student Student { get; set; }
public Course Course { set; get; }
}
在SchoolContext.cs中加入定义
public DbSet<StudentCoursePlan> StudentCoursePlan { get; set; }
增加在列出学生列表时选择指定学生,可为其增加自己选择选修课程,并计算已获取多少学分功能
在Student目录下的Index.cshtml文件添加一个按钮,按下后可以弹出一个可选定的课程列表
<td>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a> |
<a asp-action="Plan" asp-route-id="@item.ID">Plan</a>
</td>
在Students.cs中增加对StudentCoursePlan的关联
public ICollection<StudentCoursePlan> StudentCoursePlan { get; set; }
在StudentsController.cs中增加Plan的Get动作
public async Task<IActionResult> Plan(int? id)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Students
.Include(s => s.StudentCoursePlan)
.ThenInclude(e => e.Course)
.Include(e => e.Enrollments)
.ThenInclude(e => e.Course)
.AsNoTracking()
.SingleOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
PopulatePlanedCourse(student);
return View(student);
}
private void PopulatePlanedCourse(Student student)
{
List<StudentCoursePlanShowData> StudentCourseShow = new List<StudentCoursePlanShowData>();
var selectedCourse = student.StudentCoursePlan.Select(s => s.Course);
var grade = "";
int? takedCredits = null;
int? sumCredits = null;
foreach (var course in selectedCourse)
{
if (course.Enrollments != null)
{
grade = student.Enrollments.Where(i => i.CourseID == course.CourseID).SingleOrDefault().Grade.ToString();
takedCredits = course.Credits / * ( - (int)student.Enrollments.Where(i => i.CourseID == course.CourseID).SingleOrDefault().Grade);
sumCredits = (sumCredits ?? ) + takedCredits;
}
else
{
grade = "";
takedCredits = null;
}
StudentCourseShow.Add(new StudentCoursePlanShowData
{
CourseID = course.CourseID,
Title = course.Title,
Grade = grade,
TakedCredits = takedCredits
});
}
ViewData["StudentCourseShow"] = StudentCourseShow;
ViewData["showNoData"] = StudentCourseShow.Count > ? "hide" : "alert alert-warning";
ViewData["sumCredits"] = sumCredits;
ViewData["studentID"] = student.ID;
ViewData["UnselectedCourse"] = new List<StudentCoursePlanShowData>();
}
为了显示已选定的课程列表,在Models->SchoolViewModels目录下建立StudentCoursePlanShowData.cs
public class StudentCoursePlanShowData
{
public int CourseID { get; set; }
public string Title { get; set; }
public string Grade { get; set; }
public int? TakedCredits { get; set; }
}
Plan.cshtml
@model ContosoUniversity.Models.Student
@using ContosoUniversity.Models.SchoolViewModels;
@{
ViewData["Title"] = "Student Course Plan";
} <h2>The course that you ordered ... </h2> <div>
<h4>Student</h4>
<hr />
<p>Full Name : @Html.DisplayFor(model => model.FullName)</p>
<span class="badge badge-info">Course List</span>
<div class="@ViewData["showNoData"]">--没有数据--</div>
<input type="hidden" value=@Html.DisplayFor(model => model.ID)>
<table class="table table-bordered">
@if (((List<StudentCoursePlanShowData>)ViewData["StudentCourseShow"]).Count > )
{
<thead class="thead-inverse">
<tr>
<th>CourseID</th>
<th>Title</th>
<th>Grade</th>
<th>TakedCredits</th>
</tr>
</thead>
}
@foreach (var item in (List<StudentCoursePlanShowData>)ViewData["StudentCourseShow"])
{
<tr>
<td>
@Html.DisplayFor(ModeItem => item.CourseID)
</td>
<td>
@Html.DisplayFor(ModelItem => item.Title)
</td>
<td>
@Html.DisplayFor(ModelItem => item.Grade)
<div> </div>
</td>
<td>
@Html.DisplayFor(ModelItem => item.TakedCredits)
</td>
</tr>
}
</table>
@if (((List<StudentCoursePlanShowData>)ViewData["StudentCourseShow"]).Count > )
{
<div class="alert alert-success" role="alert">
<strong>Total TookCredts:</strong>@ViewData["sumCredits"]
</div>
} <div class="nav-divider">
<input class="btn btn-primary" type="button" id="btnPost" value="Post Test" data-toggle="modal" data-target="#modalSelectCourse" />
<a style="margin-left:20px" asp-action="Index">Back to List</a> @Html.AntiForgeryToken()
@section Scripts{
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript" language="JavaScript">
$(document).ready(function () {
$("#btnPost").on('click', function () {
$("#dvShowData").load('@Url.Action("GetUnselectedCourse", "Students", new { id = Model.ID })');
});
});
</script>
}
</div>
<!-- Modal -->
<div class="modal" id="modalSelectCourse" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Course List</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form asp-action="Plan">
<div class="modal-body">
<div id="dvShowData">
@{
await Html.PartialAsync("resultsUnselectedCourse", Model);
}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</form>
</div>
</div>
</div> </div>
加粗部分的js语句调用了GetUnselectedCourse方法生成未经选定的课程列表,按下Post Test按钮时弹出部分视图resultsUnselectedCourse.cshtml来显示,部分视图代码如下:
@model ContosoUniversity.Models.Student;
@using ContosoUniversity.Models.SchoolViewModels;
<h2>FullName:@Model.FullName</h2>
<table class="table">
<thead>
<tr>
<th>CourseID</th>
<th>Title</th>
<th>Credits</th>
<th>Select</th>
</tr>
</thead>
<tbody>
@foreach (var course in ((List<StudentCoursePlanShowData>)ViewData["UnselectedCourse"]))
{
<tr>
<td>@course.CourseID</td>
<td>@course.Title</td>
<td>@course.TakedCredits</td>
<td>
<input class="checkbox" type="checkbox" name="stringSelectedCourse" value="@course.CourseID" />
</td>
</tr>
}
</tbody>
</table>
列出未经选定课程的方法
public async Task<IActionResult> GetUnselectedCourse(int? id)
{
var allCourses = _context.Courses;
var viewModel = new List<StudentCoursePlanShowData>();
var student = await _context.Students.Include(s => s.StudentCoursePlan).AsNoTracking().SingleOrDefaultAsync(m => m.ID == id); if (student != null)
{
var studentSelectedCourse = new HashSet<int>(student.StudentCoursePlan.Select(c => c.CourseId)); foreach (var course in allCourses)
{
if (!studentSelectedCourse.Contains(course.CourseID))
viewModel.Add(new StudentCoursePlanShowData
{
CourseID = course.CourseID,
Title = course.Title,
TakedCredits = course.Credits
});
}
}
ViewData["UnselectedCourse"] = viewModel;
return PartialView("resultsUnselectedCourse", student);
}
选定了课程按下 Save Change 按钮时 激发 Plan 的Post 方法,记录到StudentCoursePlan表
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Plan(int? id, string[] stringSelectedCourse)
{
if (id == null)
{ return NotFound(); }
if (ModelState.IsValid)
{
UpdatePlanCourse(stringSelectedCourse, id ?? );
try
{ await _context.SaveChangesAsync();
return RedirectToAction(nameof(Plan));
}
catch (DbUpdateException)
{
ModelState.AddModelError("", "更新资料失败");
}
}
var student = await _context.Students
.Include(s => s.StudentCoursePlan)
.ThenInclude(e => e.Course)
.Include(e => e.Enrollments)
.ThenInclude(e => e.Course)
.AsNoTracking()
.SingleOrDefaultAsync(m => m.ID == id);
PopulatePlanedCourse(student);
return View(student);
} private void UpdatePlanCourse(string[] stringSelectedCourse, int studentID)
{
int j;
foreach (var course in stringSelectedCourse)
{
if (!int.TryParse(course, out j))
j = ;
_context.Add(new StudentCoursePlan
{
CourseId = j,
StudentId = studentID
});
}
}
嗯,到这里就完成了,下一步看怎么完善一下它吧!

为微软ContosoUniversity例子加上学生自选课程计划的更多相关文章
- Imagine Cup 微软“创新杯”全球学生科技大赛
一. 介绍 微软创新杯微博:http://blog.sina.com.cn/u/1733906825 官方站点:https://www.microsoft.com/china/msdn/student ...
- 【每日Scrum】第一天(4.11) TD学生助手Sprint1计划会议成果
[每日Scrum]第一天 TD学生助手Sprint1计划会议成果 ——小组成员:刘铸辉 刘静 何晓楠 谢凤娇 胡宝月 王洪叶 初次尝试敏捷开发Scrum计划流程开发项目,有什么不对的地方还希望各位大 ...
- SQLSERVER教师学生成绩课程四表联合各种SQL考题
--CREATE DATABASE EXAM_1 --GO USE EXAM_1 --判断并删除表 IF OBJECT_ID('Scores') IS NOT NULL DROP TABLE Scor ...
- mybatis多对多映射【学生与课程】
1)如图 2)创建students.sql和courses.sql和middles.sql drop table middles; drop table students; drop table co ...
- Obtaining Directory Change Notifications(微软的例子,使用FindFirstChangeNotification,FindNextChangeNotification,FindCloseChangeNotification API函数)
An application can monitor the contents of a directory and its subdirectories by using change notifi ...
- 课程计划安排 ver: 2016-12-14
录的越多,后续肯定会涨价. <x86 从实模式到保护模式> 这本书涉及到除了汇编语言,还有一些计算机架构和操作系统方面相关的知识点. 不仅为学习高级编程语言打下了非常扎实的基础,学完C++ ...
- 福大软工1816 · 课程计划预报(K班)
实践课安排 对应教学周序 时间 内容 3 09.22 业界交流讲座 6 10.13 团队选题报告答辩 7 10.20 UML设计 8 10.27 团队项目需求答辩 11 11.17 团队现场编程实战与 ...
- 【Deep Learning Nanodegree Foundation笔记】第 0 课:课程计划
第一周 机器学习的类型,以及何时使用机器学习 我们将首先简单介绍线性回归和机器学习.这将让你熟悉这些领域的常用术语,你需要了解的技术进展,并了解深度学习在更大的机器学习背景中的位置. 直播:线性回归 ...
- JPA中映射关系详细说明(一对多,多对一,一对一、多对多)、@JoinColumn、mappedBy说明
JPA中的映射关系 jpa中维护one to one ,one to many, many to one ,many to many 四种映射关系. 在每个关系中,双方中的一方在其表中拥有连接列.那么 ...
随机推荐
- openSUSE Linux 忘记root密码的解决方法
openSUSE Linux 忘记root密码的解决方法 : 对于大部分linux发行版本,忘记root密码的时候,是可以通过单用户模式来重设密码的. 如在redhat/fedora 下,可以通过在启 ...
- Spring 学习记录7 初识XmlWebApplicationContext
主题 之前Spring相关的一些类,比如Enviromnent,BenFactory都接触了一些.有一些收获.但是直接看代码很多方法都不知为什么这样写.哪里会用到.因为太底层了.不好理解..现在从高层 ...
- mysql 如何清除sql缓存
对一条sql进行优化时,发现原本很慢的一条sql(将近1分钟) 在第二次运行时, 瞬间就完成了(.00sec) 这是因为mysql对同一条sql进行了缓存,服务器直接从上次的查询结果缓存中读取数据,而 ...
- sql 添加索引强大
以前没有亲自添加过索引,今天添加了一下,果真强大.几百倍的速度提升. SELECT * FROM tbl_sys_menu m WHERE m.SID in (SELECT mr.MENU_SID F ...
- MySQL数据库篇之存储引擎
主要内容: 一.数据引擎 二.MySQL支持的存储引擎 三.使用存储引擎 1️⃣ 什么是存储引擎? MySQL中建立的库----> 文件夹,库中建立的表----->文件. 现实生活中我们用 ...
- java aop 日志打印 正则设置
package tz.lion.Utils.aop; import com.alibaba.fastjson.JSON;import org.springframework.web.multipart ...
- ie8、9 post 跨域
//显示浮层postAjax:function(url,param,callback){ var loadScore = layer_.load(1,{shade: [0.8,'#393D49']}) ...
- Mac 通过gem安装CocoaPods及Pod的使用
注:根据http://www.jianshu.com/p/6e5c0f78200a的文章做了部分修改 一.什么是CocoaPods CocoaPods是iOS项目的依赖管理工具,该项目源码在Githu ...
- Android开发实战之补间动画和属性动画
说起动画,其实一点也不陌生,在使用一款app的时候为了优化用户体验,多多少少的,都会加入动画. 安卓中的动画,分为两大类:补间动画和属性动画.本篇博文会详细介绍总结这两大动画,希望本篇博文对你的学习和 ...
- 高性能Web服务器Nginx的配置与部署研究(5)Nginx配置符号
1. 容量符号 k 千字节 K 千字节 m 兆字节 M 兆字节 2. 时间符号 ms 毫秒 s 秒 m 分 h 时 d 日 w 周 M 月(按照30天计算) y 年(按照365天计算) 3. 示例 1 ...