在之前的教程中,我们已经完成了学校的数据模型。现在我们将读取和显示相关数据,请理解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类的构造函数中,加上下面的代码。

  1. this.Configuration.LazyLoadingEnabled = false;

二、创建课程页面

1.小手动起来,生成这个页面

2.做一些改动

(1)将<h2>标题从Index改为Courses

(2)将row links放到左边

(3)为Number属性添加一个列

(4)改变列标题DepartmentID为Department

3.看看加载方式

  1. public ViewResult Index()
  2. {
  3. var courses = db.Courses.Include(c => c.Department);
  4. return View(courses.ToList());
  5. }
  1. <td>
  2. @Html.DisplayFor(modelItem => item.Department.Name)
  3. </td>

三、创建教师页面

1.为教师页面创建视图模型

创建InstructorIndexData.cs文件

  1. using System.Collections.Generic;
  2. using ContosoUniversity.Models;
  3.  
  4. namespace ContosoUniversity.ViewModels
  5. {
  6. public class InstructorIndexData
  7. {
  8. public IEnumerable<Instructor> Instructors { get; set; }
  9. public IEnumerable<Course> Courses { get; set; }
  10. public IEnumerable<Enrollment> Enrollments { get; set; }
  11. }
  12. }

2.为选中的行,添加样式
      在Content\Site.css文件中添加样式。

  1. /* info and errors */
  2. .selectedrow
  3. {
  4. background-color: #a4d4e6;
  5. }
  6. .message-info {
  7. border: 1px solid;
  8. clear: both;
  9. padding: 10px 20px;
  10. }

3.创建教师控制器和视图

(1)更改Controllers\InstructorController.cs文件

  1. using ContosoUniversity.ViewModels;
  1. public ActionResult Index(int? id, int? courseID)
  2. {
  3. var viewModel = new InstructorIndexData();
  4. viewModel.Instructors = db.Instructors
  5. .Include(i => i.OfficeAssignment)
  6. .Include(i => i.Courses.Select(c => c.Department))
  7. .OrderBy(i => i.LastName);
  8.  
  9. if (id != null)
  10. {
  11. ViewBag.InstructorID = id.Value;
  12. viewModel.Courses = viewModel.Instructors.Where(
  13. i => i.InstructorID == id.Value).Single().Courses;
  14. }
  15.  
  16. if (courseID != null)
  17. {
  18. ViewBag.CourseID = courseID.Value;
  19. viewModel.Enrollments = viewModel.Courses.Where(
  20. x => x.CourseID == courseID).Single().Enrollments;
  21. }
  22.  
  23. return View(viewModel);
  24. }

(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文件中,做些代码变动。

  1. @model ContosoUniversity.ViewModels.InstructorIndexData
  2.  
  3. @{
  4. ViewBag.Title = "Instructors";
  5. }
  6.  
  7. <h2>Instructors</h2>
  8.  
  9. <p>
  10. @Html.ActionLink("Create New", "Create")
  11. </p>
  12. <table>
  13. <tr>
  14. <th></th>
  15. <th>Last Name</th>
  16. <th>First Name</th>
  17. <th>Hire Date</th>
  18. <th>Office</th>
  19. </tr>
  20. @foreach (var item in Model.Instructors)
  21. {
  22. string selectedRow = "";
  23. if (item.InstructorID == ViewBag.InstructorID)
  24. {
  25. selectedRow = "selectedrow";
  26. }
  27. <tr class="@selectedRow" valign="top">
  28. <td>
  29. @Html.ActionLink("Select", "Index", new { id = item.InstructorID }) |
  30. @Html.ActionLink("Edit", "Edit", new { id = item.InstructorID }) |
  31. @Html.ActionLink("Details", "Details", new { id = item.InstructorID }) |
  32. @Html.ActionLink("Delete", "Delete", new { id = item.InstructorID })
  33. </td>
  34. <td>
  35. @item.LastName
  36. </td>
  37. <td>
  38. @item.FirstMidName
  39. </td>
  40. <td>
  41. @Html.DisplayFor(modelItem => item.HireDate)
  42. </td>
  43. <td>
  44. @if (item.OfficeAssignment != null)
  45. {
  46. @item.OfficeAssignment.Location
  47. }
  48. </td>
  49. </tr>
  50. }
  51. </table>

(4)显示老师相关的课程

      在Views\Instructor\Index.cshtml文件中添加代码。

  1. <td>
  2. @if (item.OfficeAssignment != null)
  3. {
  4. @item.OfficeAssignment.Location
  5. }
  6. </td>
  7. </tr>
  8. }
  9. </table>
  10.  
  11. @if (Model.Courses != null)
  12. {
  13. <h3>Courses Taught by Selected Instructor</h3>
  14. <table>
  15. <tr>
  16. <th></th>
  17. <th>ID</th>
  18. <th>Title</th>
  19. <th>Department</th>
  20. </tr>
  21.  
  22. @foreach (var item in Model.Courses)
  23. {
  24. string selectedRow = "";
  25. if (item.CourseID == ViewBag.CourseID)
  26. {
  27. selectedRow = "selectedrow";
  28. }
  29. <tr class="@selectedRow">
  30. <td>
  31. @Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
  32. </td>
  33. <td>
  34. @item.CourseID
  35. </td>
  36. <td>
  37. @item.Title
  38. </td>
  39. <td>
  40. @item.Department.Name
  41. </td>
  42. </tr>
  43. }
  44.  
  45. </table>
  46. }

(5)显示某老师教的某课程的选修情况

在Views\Instructor\Index.cshtml页面中添加代码

  1. @if (Model.Enrollments != null)
  2. {
  3. <h3>
  4. Students Enrolled in Selected Course</h3>
  5. <table>
  6. <tr>
  7. <th>Name</th>
  8. <th>Grade</th>
  9. </tr>
  10. @foreach (var item in Model.Enrollments)
  11. {
  12. <tr>
  13. <td>
  14. @item.Student.FullName
  15. </td>
  16. <td>
  17. @Html.DisplayFor(modelItem => item.Grade)
  18. </td>
  19. </tr>
  20. }
  21. </table>
  22. }

四、显式数据加载

  1. public ActionResult Index(int? id, int? courseID)
  2. {
  3. var viewModel = new InstructorIndexData();
  4.  
  5. viewModel.Instructors = db.Instructors
  6. .Include(i => i.OfficeAssignment)
  7. .Include(i => i.Courses.Select(c => c.Department))
  8. .OrderBy(i => i.LastName);
  9.  
  10. if (id != null)
  11. {
  12. ViewBag.InstructorID = id.Value;
  13. viewModel.Courses = viewModel.Instructors.Where(
  14. i => i.InstructorID == id.Value).Single().Courses;
  15. }
  16.  
  17. if (courseID != null)
  18. {
  19. ViewBag.CourseID = courseID.Value;
  20. var selectedCourse = viewModel.Courses.Where(x => x.CourseID == courseID).Single();
  21. db.Entry(selectedCourse).Collection(x => x.Enrollments).Load();
  22. foreach (Enrollment enrollment in selectedCourse.Enrollments)
  23. {
  24. db.Entry(enrollment).Reference(x => x.Student).Load();
  25. }
  26.  
  27. viewModel.Enrollments = selectedCourse.Enrollments;
  28. }
  29.  
  30. return View(viewModel);
  31. }

演练5-4:Contoso大学校园管理系统4的更多相关文章

  1. 演练5-3:Contoso大学校园管理系统3

    在前面的教程中,我们使用了一个简单的数据模型,包括三个数据实体.在这个教程汇中,我们将添加更多的实体和关系,按照特定的格式和验证规则等自定义数据模型. Contoso大学校园管理系统的数据模型如下. ...

  2. 演练5-5:Contoso大学校园管理系统5

    Contoso University示例网站演示如何使用Entity Framework 5创建ASP.NET MVC 4应用程序. Entity Framework有三种处理数据的方式:  Data ...

  3. 演练5-6:Contoso大学校园管理系统6

    在上一次的教程中,我们处理了关联数据问题.这个教程演示如何处理并发问题.你将使用Department实体创建一个页面,这个页面在支持编辑和删除的同时,还可以处理并发错误.下面的截图演示了Index页面 ...

  4. 演练5-7:Contoso大学校园管理系统(实现继承)

    ***操作视频下载:1     *** 在上一次教程中,你已经能够处理并发异常.这个教程将会展示如何在数据模型中实现继承. 在面向对象的程序设计中,你可以通过继承来清除冗余的代码.在这个教程中,你将要 ...

  5. 演练5-8:Contoso大学校园管理系统(实现存储池和工作单元模式)

    在上一次的教程中,你已经使用继承来消除在 Student 和 Instructor 实体之间的重复代码.在这个教程中,你将要看到使用存储池和工作单元模式进行增.删.改.查的一些方法.像前面的教程一样, ...

  6. 演练5-1:Contoso大学校园管理1

    **演练目的:掌握复杂模型的应用程序开发. Contoso大学校园管理系统功能包括学生.课程.教师的管理. 一.创建MVC Web应用程序 显示效果如下图,操作步骤略. 二.创建数据模型 1.创建学生 ...

  7. 演练5-2:Contoso大学校园管理2

    一.添加列标题排序功能 我们将增加Student/Index页面的功能,为列标题添加超链接,用户可以点击列标题对那一列进行排序. 1.修改Index方法 public ActionResult Ind ...

  8. Contoso 大学 - 使用 EF Code First 创建 MVC 应用,实例演练

    Contoso 大学 Web 示例应用演示了如何使用 EF 技术创建 ASP.NET MVC 应用.示例中的 Contoso 大学是虚构的.应用包括了类似学生注册.课程创建以及教师分配等功能. 这个系 ...

  9. Contoso 大学 - 7 – 处理并发

    原文 Contoso 大学 - 7 – 处理并发 By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's W ...

随机推荐

  1. .net Windows服务程序和安装程序制作图解

    最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作不成功,可能是开发环境或项目配置的不同,这里把自 ...

  2. SqlBulkCopy的使用

    1.问题:导入大数据量到数据库,用我们普通的SqlHelper来做是每插入一条都是打开连接关闭连接,这样太慢,因此我们会想到让SqlConnection一直打开直到所有数据都插入完成再关闭连接.但是根 ...

  3. 模仿jquery的一些实现 第二版

    具体如下: //w作为window的形参,就表示window (function(w) { // 定义一个全局的window.wyl变量,就类似于jquery里的$,Jquery对象 w.wyl; / ...

  4. 创建js对象和js类

    //第一种定义方式 var person=new Object(); //创建了一个对象. person.name="tom"; //使用person对象对调用name属性,它的值 ...

  5. Android 屏幕尺寸知识

    转自:http://www.zcool.com.cn/article/ZNjI3NDQ=.html 1.了解几个概念 (1)分辨率.分辨率就是手机屏幕的像素点数,一般描述成屏幕的“宽×高”,安卓手机屏 ...

  6. [LeetCode]题解(python):022-Generate Parentheses

    题目来源: https://leetcode.com/problems/generate-parentheses/ 题意分析: 题目输入一个整型n,输出n对小括号配对的所有可能性.比如说,如果输入3, ...

  7. URL参数中有 特殊符号或加密数据 的问题解决

    url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好?解决办法将这些字符转化成服务器可以识别的字符,对应关系如下:URL字符转义 用其它 ...

  8. HTTP BIN测试

    http://httpbin.org/ Tracing XML request/responses with JAX-WS: http://stackoverflow.com/questions/19 ...

  9. VCC、VDD、VEE、VSS的区别

    电路设计以及PCB制作中,经常碰见电源符号:VCC. VDD.VEE.VSS,他们具有什么样的关系那? 一.解释 VCC:C=circuit 表示电路的意思, 即接入电路的电压 VDD:D=devic ...

  10. java 抽象类与接口的区别 整理

    抽象类与接口的区别 抽象类 包含抽象方法的类就是抽象类,声明的语句:abstract class 必须是public protected 接口 对行为的抽象,声明语句:interface 抽象方法的修 ...