• 演练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.为选中的行,添加样式
          在ContentSite.css文件中添加样式。

    /* info and errors */
    .selectedrow 
    { 
        background-color: #a4d4e6; 
    }
    .message-info {
        border: 1px solid;
        clear: both;
        padding: 10px 20px;
    }

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

    (1)更改ControllersInstructorController.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视图

          在ViewsInstructorIndex.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)显示老师相关的课程

          在ViewsInstructorIndex.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)显示某老师教的某课程的选修情况

          在ViewsInstructorIndex.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);
    }
  • 相关阅读:
    callable函数,检查对象是否可调用
    eval函数的一些用法
    divmod函数使用
    sorted(x, reverse=True)
    列表、元组、字典空格的几种移除方法
    约瑟夫环问题(通过观察得出递推式从而建立递归求解)
    快速幂算法(二分思想减少连乘次数)
    素数筛(埃氏筛法与欧拉筛)
    KMP算法的详细解释
    对于线性代数的形象化理解(1)
  • 原文地址:https://www.cnblogs.com/meetyy/p/4045195.html
Copyright © 2020-2023  润新知