演练5-4:Contoso大学校园管理系统4
在之前的教程中,我们已经完成了学校的数据模型。现在我们将读取和显示相关数据,请理解EF加载导航属性的方式。
一、Lazy、Eager、Explicit数据加载
使用EF为实体中的导航属性加载相关数据,有下面几种方法。
1.Lazy loading
当实体第一次读取时,相关数据并没有获得。然而当你第一次想要访问导航属性时,导航属性的相关数据会自动获得。这产生了多次访问数据库,一次是实体数据读取,一次是导航属性读取。
2.Eager loading
当实体读取时,相关数据也一起读取,使用Include方法实现。这是通过join数据表,查询获取需要的数据。
3.Explicit loading
当你访问导航属性时,相关数据不会自动获取。你需要在代码中显式获取相关数据。
Lazying loading和Explicit Loading都称为延迟加载。
4.讨论
哪个方法性能最好?
- 读取数据库的次数比较
- 不需要读取全部记录
- 关联过于复杂
lazy loading 和 serialization不兼容,如果需要关闭lazy loading,可以使用下面两个方法:
(1)导航属性声明时,去掉virtual;
(2)在context类的构造函数中,加上下面的代码。
- this.Configuration.LazyLoadingEnabled = false;
二、创建课程页面
1.小手动起来,生成这个页面
2.做一些改动
(1)将<h2>标题从Index改为Courses
(2)将row links放到左边
(3)为Number属性添加一个列
(4)改变列标题DepartmentID为Department
3.看看加载方式
- public ViewResult Index()
- {
- var courses = db.Courses.Include(c => c.Department);
- return View(courses.ToList());
- }
- <td>
- @Html.DisplayFor(modelItem => item.Department.Name)
- </td>
三、创建教师页面
1.为教师页面创建视图模型
创建InstructorIndexData.cs文件
- using System.Collections.Generic;
- using ContosoUniversity.Models;
- namespace ContosoUniversity.ViewModels
- {
- public class InstructorIndexData
- {
- public IEnumerable<Instructor> Instructors { get; set; }
- public IEnumerable<Course> Courses { get; set; }
- public IEnumerable<Enrollment> Enrollments { get; set; }
- }
- }
2.为选中的行,添加样式
在Content\Site.css文件中添加样式。
- /* info and errors */
- .selectedrow
- {
- background-color: #a4d4e6;
- }
- .message-info {
- border: 1px solid;
- clear: both;
- padding: 10px 20px;
- }
3.创建教师控制器和视图
(1)更改Controllers\InstructorController.cs文件
- using ContosoUniversity.ViewModels;
- public ActionResult Index(int? id, int? courseID)
- {
- var viewModel = new InstructorIndexData();
- viewModel.Instructors = db.Instructors
- .Include(i => i.OfficeAssignment)
- .Include(i => i.Courses.Select(c => c.Department))
- .OrderBy(i => i.LastName);
- if (id != null)
- {
- ViewBag.InstructorID = id.Value;
- viewModel.Courses = viewModel.Instructors.Where(
- i => i.InstructorID == id.Value).Single().Courses;
- }
- if (courseID != null)
- {
- ViewBag.CourseID = courseID.Value;
- viewModel.Enrollments = viewModel.Courses.Where(
- x => x.CourseID == courseID).Single().Enrollments;
- }
- return View(viewModel);
- }
(2)分析数据加载
OfficeAssignment:它与Intructor之间是一对一的关系,我们采用了eager loading方式加载数据。因为这样做效率高,并且需要老师的OfficeAssignment都需要显示。
Course:选中某老师后,显示相关的课程信息。它与Instructor之间是多对多的关系。此处采用了eager loading方式加载数据,实际上lazy loading会更有效率,因为只需要显示选中的教师课程信息。
Enrollment:当选择了某个老师某门课程之后,相关的选修情况就会出现。Course与Enrollment之间是一对多的关系。此处采用了lazy loading方式,以后我们会换用explicit loading方式。
(3)修改教师Index视图
在Views\Instructor\Index.cshtml文件中,做些代码变动。
- @model ContosoUniversity.ViewModels.InstructorIndexData
- @{
- ViewBag.Title = "Instructors";
- }
- <h2>Instructors</h2>
- <p>
- @Html.ActionLink("Create New", "Create")
- </p>
- <table>
- <tr>
- <th></th>
- <th>Last Name</th>
- <th>First Name</th>
- <th>Hire Date</th>
- <th>Office</th>
- </tr>
- @foreach (var item in Model.Instructors)
- {
- string selectedRow = "";
- if (item.InstructorID == ViewBag.InstructorID)
- {
- selectedRow = "selectedrow";
- }
- <tr class="@selectedRow" valign="top">
- <td>
- @Html.ActionLink("Select", "Index", new { id = item.InstructorID }) |
- @Html.ActionLink("Edit", "Edit", new { id = item.InstructorID }) |
- @Html.ActionLink("Details", "Details", new { id = item.InstructorID }) |
- @Html.ActionLink("Delete", "Delete", new { id = item.InstructorID })
- </td>
- <td>
- @item.LastName
- </td>
- <td>
- @item.FirstMidName
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.HireDate)
- </td>
- <td>
- @if (item.OfficeAssignment != null)
- {
- @item.OfficeAssignment.Location
- }
- </td>
- </tr>
- }
- </table>
(4)显示老师相关的课程
在Views\Instructor\Index.cshtml文件中添加代码。
- <td>
- @if (item.OfficeAssignment != null)
- {
- @item.OfficeAssignment.Location
- }
- </td>
- </tr>
- }
- </table>
- @if (Model.Courses != null)
- {
- <h3>Courses Taught by Selected Instructor</h3>
- <table>
- <tr>
- <th></th>
- <th>ID</th>
- <th>Title</th>
- <th>Department</th>
- </tr>
- @foreach (var item in Model.Courses)
- {
- string selectedRow = "";
- if (item.CourseID == ViewBag.CourseID)
- {
- selectedRow = "selectedrow";
- }
- <tr class="@selectedRow">
- <td>
- @Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
- </td>
- <td>
- @item.CourseID
- </td>
- <td>
- @item.Title
- </td>
- <td>
- @item.Department.Name
- </td>
- </tr>
- }
- </table>
- }
(5)显示某老师教的某课程的选修情况
在Views\Instructor\Index.cshtml页面中添加代码
- @if (Model.Enrollments != null)
- {
- <h3>
- Students Enrolled in Selected Course</h3>
- <table>
- <tr>
- <th>Name</th>
- <th>Grade</th>
- </tr>
- @foreach (var item in Model.Enrollments)
- {
- <tr>
- <td>
- @item.Student.FullName
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Grade)
- </td>
- </tr>
- }
- </table>
- }
四、显式数据加载
- public ActionResult Index(int? id, int? courseID)
- {
- var viewModel = new InstructorIndexData();
- viewModel.Instructors = db.Instructors
- .Include(i => i.OfficeAssignment)
- .Include(i => i.Courses.Select(c => c.Department))
- .OrderBy(i => i.LastName);
- if (id != null)
- {
- ViewBag.InstructorID = id.Value;
- viewModel.Courses = viewModel.Instructors.Where(
- i => i.InstructorID == id.Value).Single().Courses;
- }
- if (courseID != null)
- {
- ViewBag.CourseID = courseID.Value;
- var selectedCourse = viewModel.Courses.Where(x => x.CourseID == courseID).Single();
- db.Entry(selectedCourse).Collection(x => x.Enrollments).Load();
- foreach (Enrollment enrollment in selectedCourse.Enrollments)
- {
- db.Entry(enrollment).Reference(x => x.Student).Load();
- }
- viewModel.Enrollments = selectedCourse.Enrollments;
- }
- return View(viewModel);
- }
演练5-4:Contoso大学校园管理系统4的更多相关文章
- 演练5-3:Contoso大学校园管理系统3
在前面的教程中,我们使用了一个简单的数据模型,包括三个数据实体.在这个教程汇中,我们将添加更多的实体和关系,按照特定的格式和验证规则等自定义数据模型. Contoso大学校园管理系统的数据模型如下. ...
- 演练5-5:Contoso大学校园管理系统5
Contoso University示例网站演示如何使用Entity Framework 5创建ASP.NET MVC 4应用程序. Entity Framework有三种处理数据的方式: Data ...
- 演练5-6:Contoso大学校园管理系统6
在上一次的教程中,我们处理了关联数据问题.这个教程演示如何处理并发问题.你将使用Department实体创建一个页面,这个页面在支持编辑和删除的同时,还可以处理并发错误.下面的截图演示了Index页面 ...
- 演练5-7:Contoso大学校园管理系统(实现继承)
***操作视频下载:1 *** 在上一次教程中,你已经能够处理并发异常.这个教程将会展示如何在数据模型中实现继承. 在面向对象的程序设计中,你可以通过继承来清除冗余的代码.在这个教程中,你将要 ...
- 演练5-8:Contoso大学校园管理系统(实现存储池和工作单元模式)
在上一次的教程中,你已经使用继承来消除在 Student 和 Instructor 实体之间的重复代码.在这个教程中,你将要看到使用存储池和工作单元模式进行增.删.改.查的一些方法.像前面的教程一样, ...
- 演练5-1:Contoso大学校园管理1
**演练目的:掌握复杂模型的应用程序开发. Contoso大学校园管理系统功能包括学生.课程.教师的管理. 一.创建MVC Web应用程序 显示效果如下图,操作步骤略. 二.创建数据模型 1.创建学生 ...
- 演练5-2:Contoso大学校园管理2
一.添加列标题排序功能 我们将增加Student/Index页面的功能,为列标题添加超链接,用户可以点击列标题对那一列进行排序. 1.修改Index方法 public ActionResult Ind ...
- Contoso 大学 - 使用 EF Code First 创建 MVC 应用,实例演练
Contoso 大学 Web 示例应用演示了如何使用 EF 技术创建 ASP.NET MVC 应用.示例中的 Contoso 大学是虚构的.应用包括了类似学生注册.课程创建以及教师分配等功能. 这个系 ...
- Contoso 大学 - 7 – 处理并发
原文 Contoso 大学 - 7 – 处理并发 By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's W ...
随机推荐
- .net Windows服务程序和安装程序制作图解
最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作不成功,可能是开发环境或项目配置的不同,这里把自 ...
- SqlBulkCopy的使用
1.问题:导入大数据量到数据库,用我们普通的SqlHelper来做是每插入一条都是打开连接关闭连接,这样太慢,因此我们会想到让SqlConnection一直打开直到所有数据都插入完成再关闭连接.但是根 ...
- 模仿jquery的一些实现 第二版
具体如下: //w作为window的形参,就表示window (function(w) { // 定义一个全局的window.wyl变量,就类似于jquery里的$,Jquery对象 w.wyl; / ...
- 创建js对象和js类
//第一种定义方式 var person=new Object(); //创建了一个对象. person.name="tom"; //使用person对象对调用name属性,它的值 ...
- Android 屏幕尺寸知识
转自:http://www.zcool.com.cn/article/ZNjI3NDQ=.html 1.了解几个概念 (1)分辨率.分辨率就是手机屏幕的像素点数,一般描述成屏幕的“宽×高”,安卓手机屏 ...
- [LeetCode]题解(python):022-Generate Parentheses
题目来源: https://leetcode.com/problems/generate-parentheses/ 题意分析: 题目输入一个整型n,输出n对小括号配对的所有可能性.比如说,如果输入3, ...
- URL参数中有 特殊符号或加密数据 的问题解决
url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好?解决办法将这些字符转化成服务器可以识别的字符,对应关系如下:URL字符转义 用其它 ...
- HTTP BIN测试
http://httpbin.org/ Tracing XML request/responses with JAX-WS: http://stackoverflow.com/questions/19 ...
- VCC、VDD、VEE、VSS的区别
电路设计以及PCB制作中,经常碰见电源符号:VCC. VDD.VEE.VSS,他们具有什么样的关系那? 一.解释 VCC:C=circuit 表示电路的意思, 即接入电路的电压 VDD:D=devic ...
- java 抽象类与接口的区别 整理
抽象类与接口的区别 抽象类 包含抽象方法的类就是抽象类,声明的语句:abstract class 必须是public protected 接口 对行为的抽象,声明语句:interface 抽象方法的修 ...