ASP.NET Core MVC 和 Entity Framework Core 入門教程 - 讀取相關(guān)數(shù)據(jù)(六)

Contoso 大學(xué)示例 Web 應(yīng)用程序演示如何使用實體框架(EF)Core 2.0 和 Visual Studio 2017 創(chuàng)建 ASP.NET Core 2.0 MVC Web 應(yīng)用程序聪姿。 如欲了解更多本教程相關(guān)信息缕碎,請參閱 一谴轮、入門
在上一教程中挂洛,您完成了學(xué)校數(shù)據(jù)模型。在本章中超营,您將讀取和展示相關(guān)數(shù)據(jù) -- 即鸳玩,實體框架加載到導(dǎo)航屬性的數(shù)據(jù)。
以下圖片展示了您即將完成的頁面演闭。

image.png

image.png

相關(guān)數(shù)據(jù)的 Eager Loading (貪婪加載), Explicit Loading (顯式加載), 和 Lazy Loading (懶加載)

ORM (對象關(guān)系映射)框架不跟,例如說 Entity Framework, 通常有多種方式用于加載實體的導(dǎo)航屬性米碰。

  • Eager loading -- 貪婪加載窝革。 當(dāng)讀取實體的時候购城,也讀取實體相關(guān)的數(shù)據(jù)。這通常導(dǎo)致一個單一連接查詢聊闯,來取出所以需要的數(shù)據(jù)工猜。在 Entity Framework 使用 IncludeThenInclude 方法來指定貪婪加載米诉。
    image.png

    您可以在分離的查詢中檢索其中一些數(shù)據(jù)菱蔬, 然后讓 EF “修復(fù)” 導(dǎo)航屬性。 也就是說史侣, EF 會自動將分離查詢中的實體添加到之前讀取到的實體導(dǎo)航屬性中拴泌。 對于檢索相關(guān)數(shù)據(jù)的查詢, 您可以使用 Load 方法代替那些返回一個 listobject 的方法惊橱,比如說 ToListSingle 蚪腐。
    image.png
  • Explicit loading -- 顯示加載。第一次讀取實體時税朴, 相關(guān)的數(shù)據(jù)沒有被檢索回季。當(dāng)您需要的時候,您需要寫代碼來檢索相關(guān)數(shù)據(jù)正林。 如同在貪婪加載中使用分離查詢一樣泡一,顯示加載將形成多個查詢送往數(shù)據(jù)庫。不同之處在于觅廓,使用顯示加載鼻忠,代碼指定的是要加載的導(dǎo)航屬性。在 Entity Framework 1.1 中您可以使用 Load 方法來執(zhí)行顯示加載杈绸。例如:
    image.png
  • Lazy loading -- 懶加載帖蔓,或延遲加載。第一次讀取實體時瞳脓, 相關(guān)的數(shù)據(jù)沒有被檢索塑娇。但是,當(dāng)您嘗試訪問導(dǎo)航屬性時劫侧,導(dǎo)航屬性相關(guān)的數(shù)據(jù)將會被自動檢索出埋酬。當(dāng)您首次訪問導(dǎo)航屬性時,將有一個查詢發(fā)往數(shù)據(jù)庫板辽。 Entity Framework Core 1.0 不支持 Lazy loading 奇瘦。

性能注意事項

如果您事先知道,對于每個實體劲弦,需要相關(guān)的數(shù)據(jù)的話耳标,貪婪加載通常提供了最佳性能,因為發(fā)送到數(shù)據(jù)庫的一個查詢通常比多個查詢更有效率邑跪。 例如次坡,假設(shè)每個部門有十個相關(guān)的課程呼猪,貪婪加載方法使用了一條查詢加載一個部門的所有相關(guān)數(shù)據(jù),只需要一次數(shù)據(jù)庫往返砸琅。而對每個部門單獨(dú)查詢課程宋距,將導(dǎo)致出現(xiàn)十一個數(shù)據(jù)庫往返。多余的數(shù)據(jù)庫往返在延遲較高時對性能特別不利症脂。
另一方面谚赎,在某些情況下,單獨(dú)查詢會更加高效诱篷。 貪婪加載可能會導(dǎo)致非常復(fù)雜的聯(lián)結(jié)查詢以至于 SQL Server 無法有效處理壶唤。 或者,您只需要對一個實體集的某個子集訪問其導(dǎo)航屬性棕所,單獨(dú)查詢將可能比貪婪加載表現(xiàn)得更好闸盔,因為貪婪加載加載了超出您需要的數(shù)據(jù)的原因。 如果性能對您非常重要的話琳省,最好對兩種方式都進(jìn)行測試來做出最佳的選擇迎吵。

創(chuàng)建課程頁,其中顯示部門名稱针贬。

Course 實體包含一個導(dǎo)航屬性击费,對應(yīng)課程所分配部門的 Department 實體。 若要在 Course (課程)列表中顯示所分配 Department (部門)的名稱坚踩,您需要從 Course.Department 導(dǎo)航屬性連接的 Department 實體中取得 Name 屬性荡灾。
Course 實體類型創(chuàng)建一個控制器,命名為 CoursesController瞬铸,使用前面教程中用于創(chuàng)建 Students 控制器時用的腳手架批幌,相同的選項 -- “視圖使用 Entity Framework 的 MVC 控制器”。如下所示:

image.png

打開 CoursesController.cs 文件嗓节,檢查 Index 方法荧缘。腳手架已自動使用 Include 方法指定 Department 導(dǎo)航屬性為貪婪加載。
Index 方法替換為以下代碼拦宣, 使用一個更合適的名稱命名返回 Course 實體的 IQueryable 對象截粗。

public async Task<IActionResult> Index()
{
    var courses = _context.Courses
        .Include(c => c.Department)
        .AsNoTracking();
    return View(await courses.ToListAsync());
}

打開 Views/Courses/Index.cshtl,并使用以下代碼替換模板代碼鸵隧。

@model IEnumerable<ContosoUniversity.Models.Course>
@{
    ViewData["Title"] = "Courses";
}
<h2>Courses</h2>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.CourseID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Credits)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Department)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.CourseID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Title)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Credits)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Department.Name)
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@item.CourseID">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.CourseID">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.CourseID">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

您對腳手架生成的代碼作了如下更改:

  • 修改了課程 Index 頁面的標(biāo)題
  • 添加了一列用于顯示 CourseID 屬性绸罗。 默認(rèn)情況下, 主鍵不會出現(xiàn)在腳手架代碼中豆瘫,因為它們通常對最終用戶無意義珊蟀。 然而, 在這兒外驱,主鍵是有意義的育灸,您打算顯示出來腻窒。
  • 修改 Department 列以顯示部門名稱。 代碼顯示加載到 Department 導(dǎo)航屬性中 Department 實體的 Name 屬性磅崭。
@Html.DisplayFor(modelItem => item.Department.Name)

運(yùn)行應(yīng)用程序儿子,選擇 Course 菜單以查看含有部門名稱的列表。

image.png

創(chuàng)建一個教師頁面砸喻,其中顯示課程及學(xué)生注冊情況

在本節(jié)中柔逼,您將會為 Instructor 實體創(chuàng)建一個控制器和視圖用于展示教師。

image.png

本頁面使用以下方法讀取并展示相關(guān)數(shù)據(jù):

  • 教師列表展示來自 OfficeAssignment 實體的相關(guān)數(shù)據(jù)恩够。InstructorOfficeeAssignment 實體是 一 對 零或一 關(guān)系卒落,對 OfficeAssignment 實體將使用貪婪加載方式。 如前所述蜂桶, 當(dāng)您需要主表所有行的相關(guān)數(shù)據(jù)時,貪婪加載是最高效的也切。 在這種情況下扑媚, 你希望顯示所有教師分配的辦公室。
  • 當(dāng)用戶選擇一個教師時雷恃,相關(guān)的課程實體將會顯示疆股。 教師和課程實體是 “多對多” 關(guān)系。您將對課程及相關(guān)的部門實體使用貪婪加載倒槐。此時旬痹,單獨(dú)的查詢可能會更加高效,因為您只需要所選擇教師相關(guān)的課程讨越。 不過两残,這個示例主要用于展示如何對導(dǎo)航屬性使用貪婪加載,以及對導(dǎo)航屬性內(nèi)的實體進(jìn)行貪婪加載把跨。
  • 當(dāng)用戶選擇一個課程時人弓,相關(guān)的注冊實體將會顯示。 課程和注冊實體是 “一對多” 關(guān)系着逐。 您將會使用單獨(dú)的查詢來應(yīng)對注冊實體和相關(guān)的學(xué)生實體崔赌。

創(chuàng)建教師索引視圖的視圖模型

教師頁顯示三個不同的表中的數(shù)據(jù)。因此耸别,你創(chuàng)建的視圖模型將包括三個屬性健芭,每個屬性包含一個表的數(shù)據(jù)。
在 SchoolViewModels 文件夾中秀姐,創(chuàng)建 InstructorIndexData.cs 并替換為以下代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ContosoUniversity.Models.SchoolViewModels
{
    public class InstructorIndexData
    {
        public IEnumerable<Instructor> Instructors { get; set; }
        public IEnumerable<Course> Courses { get; set; }
        public IEnumerable<Enrollment> Enrollments { get; set; }
    }
}

創(chuàng)建教師控制器和視圖

使用包含 EF 讀/寫 操作的控制器模板創(chuàng)建一個教師控制器慈迈,如下圖所示:


image.png

打開 InstructorsController.cs 和添加 Viewmodel 命名空間引用:

using ContosoUniversity.Models.SchoolViewModels;

使用以下代碼替換 Index 方法,以達(dá)到相關(guān)數(shù)據(jù)的貪婪加載囊扳,并放入視圖模型中吩翻。

public async Task<IActionResult> Index(int? id, int? courseID)
{
    var viewModel = new InstructorIndexData();
    viewModel.Instructors = await _context.Instructors
          .Include(i => i.OfficeAssignment)
          .Include(i => i.CourseAssignments)
            .ThenInclude(i => i.Course)
                .ThenInclude(i => i.Enrollments)
                    .ThenInclude(i => i.Student)
          .Include(i => i.CourseAssignments)
            .ThenInclude(i => i.Course)
                .ThenInclude(i => i.Department)
          .AsNoTracking()
          .OrderBy(i => i.LastName)
          .ToListAsync();
    
    if (id != null)
    {
        ViewData["InstructorID"] = id.Value;
        Instructor instructor = viewModel.Instructors.Where(
            i => i.ID == id.Value).Single();
        viewModel.Courses = instructor.CourseAssignments.Select(s => s.Course);
    }

    if (courseID != null)
    {
        ViewData["CourseID"] = courseID.Value;
        viewModel.Enrollments = viewModel.Courses.Where(
            x => x.CourseID == courseID).Single().Enrollments;
    }

    return View(viewModel);
}

方法接受可選路由數(shù)據(jù)(id)和一個查詢字符串參數(shù)(courseID)兜看,分別對應(yīng)選擇的教師和選擇的課程。參數(shù)從頁面的超鏈接中而來狭瞎。
代碼首先創(chuàng)建一個視圖模型的實例细移,并在其中加入教師列表。 代碼指定對 Instrator.OfficeAssignmentCourseAssignments 導(dǎo)航屬性使用貪婪加載熊锭。 在 CourseAssignments 屬性中弧轧,Course 屬性將被加載, 然后在 Course 屬性中碗殷, EnrollmentsDepartment 屬性將會被加載精绎,同時在每個 Enrollment 實體中, Student 屬性將會被加載锌妻。

viewModel.Instructors = await _context.Instructors
      .Include(i => i.OfficeAssignment)
      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Enrollments)
                .ThenInclude(i => i.Student)
      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Department)
      .AsNoTracking()
      .OrderBy(i => i.LastName)
      .ToListAsync();

由于視圖始終需要 OfficeAssignmet 實體代乃,因此在同一個查詢中獲取它更有效。 當(dāng)在網(wǎng)頁中選擇教師時仿粹,課程實體是必需的搁吓,因此只有當(dāng)頁面以不是沒有選擇的課程更頻繁地顯示時,單個查詢才會比多個查詢更好吭历。
代碼中堕仔,CourseAssignmentsCourse 重復(fù)出現(xiàn),因為您需要 Course 的兩個屬性晌区。 在第一個 ThenInclude 中獲取 CourseAssignment.Course, Course.Enrollements, 及 Enrollment.Student 摩骨。

viewModel.Instructors = await _context.Instructors
      .Include(i => i.OfficeAssignment)
      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Enrollments)
                .ThenInclude(i => i.Student)
      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Department)
      .AsNoTracking()
      .OrderBy(i => i.LastName)
      .ToListAsync();

在代碼中的那一點(diǎn),另一個 ThenInclude 將用于學(xué)生的導(dǎo)航屬性朗若,您不需要它恼五。 但是,調(diào)用 Include 是由 Instructor 屬性開始的捡偏,所以你必須重新遍歷整個鏈條唤冈,通過指定 Course.Department 而不是 Course.Enrollments

viewModel.Instructors = await _context.Instructors
      .Include(i => i.OfficeAssignment)
      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Enrollments)
                .ThenInclude(i => i.Student)
      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Department)
      .AsNoTracking()
      .OrderBy(i => i.LastName)
      .ToListAsync();

在選擇了一個教師時银伟,將執(zhí)行下面的代碼你虹。 從教師視圖模型中的列表中檢索所選的教師。 然后視圖模型的Courses 屬性和課程實體從該教師的 CourseAssignments 導(dǎo)航屬性中一起被加載彤避。

if (id != null)
{
    ViewData["InstructorID"] = id.Value;
    Instructor instructor = viewModel.Instructors.Where(
        i => i.ID == id.Value).Single();
    viewModel.Courses = instructor.CourseAssignments.Select(s => s.Course);
}

Where 方法返回一個集合傅物,但在本例中,傳遞給該方法的條件只會返回一個 Instructor 實體琉预。 Single 方法將集合轉(zhuǎn)換為單個 Instructor 實體董饰, 這樣一來,您就可以訪問該實體的 CourseAssignments 屬性。 CourseAssignments 包含 CourseAssignments 實體集合卒暂,從中得到相關(guān)的 Course 實體集啄栓。
當(dāng)您知道集合將只有一個項目時,您可以在集合上使用 Single 方法也祠。如果傳遞給它的集合為空昙楚,或者有多個項目, Single 方法會拋出異常诈嘿。一個替代方法是 SingleOrDefault 堪旧,如果集合是空的,它返回一個默認(rèn)值(在這種情況下為null)奖亚。 但是淳梦,在這種情況下,仍然會導(dǎo)致異常(嘗試在空引用上查找Courses屬性)昔字,并且異常消息將不太清楚地指出問題的原因爆袍。 當(dāng)您調(diào)用 Single 方法時,您還可以傳遞 Where 條件李滴,而無需單獨(dú)調(diào)用 Where 方法:

.Single(i => i.ID == id.Value)

而不是

.Where(I => i.ID == id.Value).Single()

接下來螃宙,如果選擇課程,則從視圖模型中的課程列表中檢索所選課程所坯。 然后,視圖模型的 “Enrollments” 屬性將加載該課程的 “Enrollments” 導(dǎo)航屬性中的 “Enrollment” 實體挂捅。

if (courseID != null)
{
    ViewData["CourseID"] = courseID.Value;
    viewModel.Enrollments = viewModel.Courses.Where(
        x => x.CourseID == courseID).Single().Enrollments;
}

修改 “教師索引” 視圖

在 Views/Instructors/Index.cshtml 文件中芹助,使用以下代碼替換。

@model ContosoUniversity.Models.SchoolViewModels.InstructorIndexData
@{
    ViewData["Title"] = "Instructors";
}
<h2>Instructors</h2>
<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>Last Name</th>
            <th>First Name</th>
            <th>Hire Date</th>
            <th>Office</th>
            <th>Courses</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Instructors)
        {
            string selectedRow = "";
            if (item.ID == (int?)ViewData["InstructorID"])
            {
                selectedRow = "success";
            }
            <tr class="@selectedRow">
                <td>
                    @Html.DisplayFor(modelItem => item.LastName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.FirstMidName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.HireDate)
                </td>
                <td>
                    @if (item.OfficeAssignment != null)
                    {
                        @item.OfficeAssignment.Location
                    }
                </td>
                <td>
                    @{
                        foreach (var course in item.CourseAssignments)
                        {
                            @course.Course.CourseID @:  @course.Course.Title <br />
                        }
                    }
                </td>
                <td>
                    <a asp-action="Index" asp-route-id="@item.ID">Select</a> |
                    <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>
                </td>
            </tr>
           }
    </tbody>
</table>

你對現(xiàn)有代碼做出以下更改:

  • 修改頁面 model 類為 InstructorIndexData闲先。
  • 修改頁面標(biāo)題為 Instructors 状土。
  • item.OfficeAssignment 不為空的情況下,才添加一個 Office 列伺糠,顯示 item.OfficeAssignment.Location 蒙谓。 (因為這是一個 "一 對 零或一" 的關(guān)系,可能沒有相關(guān)的 OfficeAssignment 實體训桶。)
    @if (item.OfficeAssignment != null)
    {
        @item.OfficeAssignment.Location
    }
    
  • 添加了一個課程列累驮,顯示每個教師所教授的課程。 請參閱 使用 @: 的顯式行轉(zhuǎn)換 有關(guān)此 Razor 語法的更多信息舵揭。
  • 添加的代碼動態(tài)地將 class =“success” 添加到所選教師的 tr 元素中谤专。 這將會通過 Bootstrap 類為選擇行設(shè)置一個背景顏色。
    string selectedRow = "";
    if (item.ID == (int?)ViewData["InstructorID"])
    {
       selectedRow = "success";
    }
    <tr class="@selectedRow">
    
  • 在每行中的其他鏈接前午绳,添加一個新的超鏈接 "Select" 置侍,將所選教師的 ID 發(fā)送到 Index 方法。
    <a asp-action="Index" asp-route-id="@item.ID">Select</a> |
    

運(yùn)行應(yīng)用程序,選擇 Instructor 鏈接蜡坊。 當(dāng)沒有相關(guān)的 OfficeAssignment 實體時杠输,該頁面顯示相關(guān) OfficeAssignment 實體的 Location 屬性和一個空表單元格。

image.png

Views/Instructors/Index.cshtml 文件中秕衙,在 </table> 標(biāo)簽(文件末尾)后添加以下代碼蠢甲。 該代碼顯示了當(dāng)教師選擇時與教練相關(guān)的課程列表。

@if (Model.Courses != null)
{
    <h3>Courses Taught by Selected Instructor</h3>
    <table class="table">
        <tr>
            <th></th>
            <th>Number</th>
            <th>Title</th>
            <th>Department</th>
        </tr>

        @foreach (var item in Model.Courses)
        {
            string selectedRow = "";
            if (item.CourseID == (int?)ViewData["CourseID"])
            {
                selectedRow = "success";
            }
            <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>
}

此代碼讀取視圖模型的 Courses 屬性以顯示課程列表灾梦。它還提供一個選擇超鏈接峡钓,將所選課程的 ID 發(fā)送到 Index 操作方法。
刷新頁面并選擇一個教練若河。 現(xiàn)在能岩,您看到一個網(wǎng)格,顯示分配給所選教師的課程萧福,并且每個課程都會看到所分配部門的名稱拉鹃。

image.png

在您剛剛添加的代碼塊之后,添加以下代碼鲫忍。 這將顯示在選擇課程時注冊該課程的學(xué)生列表膏燕。

@if (Model.Enrollments != null)
{
    <h3>
        Students Enrolled in Selected Course
    </h3>
    <table class="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>
}

該代碼讀取視圖模型的 Enrollments 屬性,以顯示在課程中注冊的學(xué)生列表悟民。
再次刷新頁面并選擇一個教師坝辫。 然后選擇一個課程,查看注冊學(xué)生及其成績的列表射亏。

image.png

顯式加載

當(dāng)您在 InstructorsController.cs 中檢索到教師列表時近忙,您為 CourseAssignments 導(dǎo)航屬性指定了貪婪加載。
假設(shè)您期望用戶很少想要在選定的教練和課程中看到注冊智润。 在這種情況下及舍,您可能只需要請求加載注冊數(shù)據(jù)。 要查看如何進(jìn)行顯式加載的示例窟绷,請使用以下代碼替換 Index 方法锯玛,這將刪除 Enrollments 的貪婪加載然后顯式加載該屬性。

public async Task<IActionResult> Index(int? id, int? courseID)
{
    var viewModel = new InstructorIndexData();
    viewModel.Instructors = await _context.Instructors
          .Include(i => i.OfficeAssignment)
          .Include(i => i.CourseAssignments)
            .ThenInclude(i => i.Course)
                .ThenInclude(i => i.Department)
          .OrderBy(i => i.LastName)
          .ToListAsync();
    if (id != null)
    {
        ViewData["InstructorID"] = id.Value;
        Instructor instructor = viewModel.Instructors.Where(
            i => i.ID == id.Value).Single();
        viewModel.Courses = instructor.CourseAssignments.Select(s => s.Course);
    }
    if (courseID != null)
    {
        ViewData["CourseID"] = courseID.Value;
        var selectedCourse = viewModel.Courses.Where(x => x.CourseID == courseID).Single();
        await _context.Entry(selectedCourse).Collection(x => x.Enrollments).LoadAsync();
        foreach (Enrollment enrollment in selectedCourse.Enrollments)
        {
            await _context.Entry(enrollment).Reference(x => x.Student).LoadAsync();
        }
        viewModel.Enrollments = selectedCourse.Enrollments;
    }
    return View(viewModel);
}

新代碼從用于檢索教師實體的代碼中刪除 Enrollment 數(shù)據(jù)的 ThenInclude 方法調(diào)用兼蜈。如果選擇了教員和課程攘残,高亮部分的代碼將檢索所選課程的注冊實體,以及每個注冊的學(xué)生實體饭尝。
運(yùn)行應(yīng)用程序肯腕,選擇 Instructor 鏈接。 可以看到钥平,雖然您已經(jīng)更改了數(shù)據(jù)的檢索方式实撒, 頁面上顯示的內(nèi)容并沒有任何區(qū)別于之前的姊途。

小結(jié)

您現(xiàn)在已經(jīng)使用貪婪加載,在一個查詢及多個查詢中用于讀取相關(guān)數(shù)據(jù)到導(dǎo)航屬性知态。 在下一個教程中捷兰,您將學(xué)習(xí)如何更新相關(guān)數(shù)據(jù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末负敏,一起剝皮案震驚了整個濱河市贡茅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌其做,老刑警劉巖顶考,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妖泄,居然都是意外死亡驹沿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門蹈胡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渊季,“玉大人,你說我怎么就攤上這事罚渐∪春海” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵荷并,是天一觀的道長合砂。 經(jīng)常有香客問我,道長源织,這世上最難降的妖魔是什么既穆? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮雀鹃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘励两。我一直安慰自己黎茎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布当悔。 她就那樣靜靜地躺著傅瞻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盲憎。 梳的紋絲不亂的頭發(fā)上嗅骄,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音饼疙,去河邊找鬼溺森。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屏积。 我是一名探鬼主播医窿,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼炊林!你這毒婦竟也來了姥卢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤渣聚,失蹤者是張志新(化名)和其女友劉穎独榴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奕枝,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棺榔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了倍权。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掷豺。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖薄声,靈堂內(nèi)的尸體忽然破棺而出当船,到底是詐尸還是另有隱情,我是刑警寧澤默辨,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布德频,位于F島的核電站,受9級特大地震影響缩幸,放射性物質(zhì)發(fā)生泄漏壹置。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一表谊、第九天 我趴在偏房一處隱蔽的房頂上張望澳叉。 院中可真熱鬧,春花似錦炮沐、人聲如沸泛烙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽余佃。三九已至,卻和暖如春跨算,著一層夾襖步出監(jiān)牢的瞬間爆土,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工诸蚕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留步势,地道東北人氧猬。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像立润,于是被迫代替她去往敵國和親狂窑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容