ASP.NET Core 中的 Razor 頁面和 EF Core - 讀取相關數(shù)據(jù)

2019-04-17 08:58 更新

在本教程中,將讀取和顯示相關數(shù)據(jù)。 相關數(shù)據(jù)為 EF Core 加載到導航屬性中的數(shù)據(jù)。

如果遇到無法解決的問題,請下載或查看已完成的應用。 下載說明。

下圖顯示了本教程中已完成的頁面:

“課程索引”頁

“講師索引”頁

相關數(shù)據(jù)的預先加載、顯式加載和延遲加載

EF Core 可采用多種方式將相關數(shù)據(jù)加載到實體的導航屬性中:

  • 預先加載。 預先加載是指對查詢某類型的實體時一并加載相關實體。 讀取實體時,會檢索其相關數(shù)據(jù)。 此時通常會出現(xiàn)單一聯(lián)接查詢,檢索所有必需數(shù)據(jù)。 EF Core 將針對預先加載的某些類型發(fā)出多個查詢。 與存在單一查詢的 EF6 中的某些查詢相比,發(fā)出多個查詢可能更有效。 預先加載通過 Include 和 ThenInclude 方法進行指定。預先加載示例當包含集合導航時,預先加載會發(fā)送多個查詢:一個查詢用于主查詢一個查詢用于加載樹中每個集合“邊緣”。
  • 使用 Load 的單獨查詢:可在單獨的查詢中檢索數(shù)據(jù),EF Core 會“修復”導航屬性。 “修復”是指 EF Core 自動填充導航屬性。 與預先加載相比,使用 Load 的單獨查詢更像是顯式加載。單獨查詢示例注意:EF Core 會將導航屬性自動“修復”為之前加載到上下文實例中的任何其他實體。 即使導航屬性的數(shù)據(jù)非顯式包含在內(nèi),但如果先前加載了部分或所有相關實體,則仍可能填充該屬性。
  • 顯式加載。 首次讀取實體時,不檢索相關數(shù)據(jù)。 必須編寫代碼才能在需要時檢索相關數(shù)據(jù)。 使用單獨查詢進行顯式加載時,會向數(shù)據(jù)庫發(fā)送多個查詢。 該代碼通過顯式加載指定要加載的導航屬性。 使用 Load 方法進行顯式加載。 例如:顯式加載示例
  • 延遲加載。 延遲加載已添加到版本 2.1 中的 EF Core。 首次讀取實體時,不檢索相關數(shù)據(jù)。 首次訪問導航屬性時,會自動檢索該導航屬性所需的數(shù)據(jù)。 首次訪問導航屬性時,都會向數(shù)據(jù)庫發(fā)送一個查詢。
  • Select 運算符僅加載所需的相關數(shù)據(jù)。

創(chuàng)建顯示院系名稱的“課程”頁

課程實體包括一個帶 Department 實體的導航屬性。 Department 實體包含要分配課程的院系。

要在課程列表中顯示已分配院系的名稱:

  • 從 Department 實體中獲取 Name 屬性。
  • Department 實體來自于 Course.Department 導航屬性。

Course.Department

為課程模型創(chuàng)建基架

按照為“學生”模型搭建基架中的說明操作,并對模型類使用 Course。

上述命令為 Course 模型創(chuàng)建基架。 在 Visual Studio 中打開項目。

打開 Pages/Courses/Index.cshtml.cs 并檢查 OnGetAsync 方法。 基架引擎為 Department 導航屬性指定了預先加載。 Include 方法指定預先加載。

運行應用并選擇“課程”鏈接。 院系列顯示 DepartmentID(該項無用)。

使用以下代碼更新 OnGetAsync 方法:

C#

public async Task OnGetAsync()
{
    Course = await _context.Courses
        .Include(c => c.Department)
        .AsNoTracking()
        .ToListAsync();
}

上述代碼添加了 AsNoTracking。 由于未跟蹤返回的實體,因此 AsNoTracking 提升了性能。 未跟蹤實體,因為未在當前上下文中更新這些實體。

使用以下突出顯示的標記更新 Pages/Courses/Index.cshtml:

HTML

@page
@model ContosoUniversity.Pages.Courses.IndexModel
@{
    ViewData["Title"] = "Courses";
}

<h2>Courses</h2>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Course[0].CourseID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Course[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Course[0].Credits)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Course[0].Department)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Course)
        {
            <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-page="./Edit" asp-route-id="@item.CourseID">Edit</a> |
                    <a asp-page="./Details" asp-route-id="@item.CourseID">Details</a> |
                    <a asp-page="./Delete" asp-route-id="@item.CourseID">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

對基架代碼進行了以下更改:

  • 將標題從“索引”更改為“課程”。
  • 添加了顯示 CourseID 屬性值的“數(shù)字”列。 默認情況下,不針對主鍵進行架構(gòu),因為對最終用戶而言,它們通常沒有意義。 但在此情況下主鍵是有意義的。
  • 更改“院系”列,顯示院系名稱。 該代碼顯示已加載到 Department 導航屬性中的 Department實體的 Name 屬性:HTML復制@Html.DisplayFor(modelItem => item.Department.Name)

運行應用并選擇“課程”選項卡,查看包含系名稱的列表。

“課程索引”頁

使用 Select 加載相關數(shù)據(jù)

OnGetAsync 方法使用 Include 方法加載相關數(shù)據(jù):

C#

public async Task OnGetAsync()
{
    Course = await _context.Courses
        .Include(c => c.Department)
        .AsNoTracking()
        .ToListAsync();
}

Select 運算符僅加載所需的相關數(shù)據(jù)。 對于單個項(如 Department.Name),它使用 SQL INNER JOIN。 對于集合,它使用另一個數(shù)據(jù)庫訪問,但集合上的 Include 運算符也是如此。

以下代碼使用 Select 方法加載相關數(shù)據(jù):

C#

public IList<CourseViewModel> CourseVM { get; set; }

public async Task OnGetAsync()
{
    CourseVM = await _context.Courses
            .Select(p => new CourseViewModel
            {
                CourseID = p.CourseID,
                Title = p.Title,
                Credits = p.Credits,
                DepartmentName = p.Department.Name
            }).ToListAsync();
}

CourseViewModel:

C#

public class CourseViewModel
{
    public int CourseID { get; set; }
    public string Title { get; set; }
    public int Credits { get; set; }
    public string DepartmentName { get; set; }
}

有關完整示例的信息,請參閱 IndexSelect.cshtml 和 IndexSelect.cshtml.cs

創(chuàng)建顯示“課程”和“注冊”的“講師”頁

在本部分中,將創(chuàng)建“講師”頁。

“講師索引”頁

該頁面通過以下方式讀取和顯示相關數(shù)據(jù):

  • 講師列表顯示 OfficeAssignment 實體(上圖中的辦公室)的相關數(shù)據(jù)。 Instructor 和 OfficeAssignment 實體之間存在一對零或一的關系。 預先加載適用于 OfficeAssignment 實體。 需要顯示相關數(shù)據(jù)時,預先加載通常更高效。 在此情況下,會顯示講師的辦公室分配。
  • 當用戶選擇一名講師(上圖中的 Harui)時,顯示相關的 Course 實體。 Instructor 和 Course 實體之間存在多對多關系。 對 Course 實體及其相關的 Department 實體使用預先加載。 這種情況下,單獨查詢可能更有效,因為僅需顯示所選講師的課程。 此示例演示如何在位于導航實體內(nèi)的實體中預先加載這些導航實體。
  • 當用戶選擇一門課程(上圖中的化學)時,顯示 Enrollments 實體的相關數(shù)據(jù)。 上圖中顯示了學生姓名和成績。 Course 和 Enrollment 實體之間存在一對多的關系。

創(chuàng)建“講師索引”視圖的視圖模型

“講師”頁顯示來自三個不同表格的數(shù)據(jù)。 創(chuàng)建一個視圖模型,該模型中包含表示三個表格的三個實體。

在 SchoolViewModels 文件夾中,使用以下代碼創(chuàng)建 InstructorIndexData.cs:

C#

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)建基架

按照為“學生”模型搭建基架中的說明操作,并對模型類使用 Instructor。

上述命令為 Instructor 模型創(chuàng)建基架。 運行應用并導航到“講師”頁。

將 Pages/Instructors/Index.cshtml.cs 替換為以下代碼:

C#

using ContosoUniversity.Models;
using ContosoUniversity.Models.SchoolViewModels;  // Add VM
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading.Tasks;

namespace ContosoUniversity.Pages.Instructors
{
    public class IndexModel : PageModel
    {
        private readonly ContosoUniversity.Data.SchoolContext _context;

        public IndexModel(ContosoUniversity.Data.SchoolContext context)
        {
            _context = context;
        }

        public InstructorIndexData Instructor { get; set; }
        public int InstructorID { get; set; }

        public async Task OnGetAsync(int? id)
        {
            Instructor = new InstructorIndexData();
            Instructor.Instructors = await _context.Instructors
                  .Include(i => i.OfficeAssignment)
                  .Include(i => i.CourseAssignments)
                    .ThenInclude(i => i.Course)
                  .AsNoTracking()
                  .OrderBy(i => i.LastName)
                  .ToListAsync();

            if (id != null)
            {
                InstructorID = id.Value;
            }           
        }
    }
}

OnGetAsync 方法接受所選講師 ID 的可選路由數(shù)據(jù)。

檢查 Pages/Instructors/Index.cshtml.cs 文件中的查詢:

C#

Instructor.Instructors = await _context.Instructors
      .Include(i => i.OfficeAssignment)
      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
      .AsNoTracking()
      .OrderBy(i => i.LastName)
      .ToListAsync();

查詢包括兩項內(nèi)容:

  • OfficeAssignment:在講師視圖中顯示。
  • CourseAssignments:課程的教學內(nèi)容。

更新“講師索引”頁

使用以下標記更新 Pages/Instructors/Index.cshtml:

HTML

@page "{id:int?}"
@model ContosoUniversity.Pages.Instructors.IndexModel

@{
    ViewData["Title"] = "Instructors";
}

<h2>Instructors</h2>

<p>
    <a asp-page="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.Instructor.Instructors)
        {
            string selectedRow = "";
            if (item.ID == Model.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-page="./Index" asp-route-id="@item.ID">Select</a> |
                    <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                    <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                    <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

上述標記進行以下更改:

  • 將 page 指令從 @page 更新為 @page "{id:int?}"。 "{id:int?}" 是一個路由模板。 路由模板將 URL 中的整數(shù)查詢字符串更改為路由數(shù)據(jù)。 例如,單擊僅具有 @page 指令的講師的“選擇”鏈接將生成如下 URL:http://localhost:1234/Instructors?id=2當頁面指令是 @page "{id:int?}" 時,之前的 URL 為:http://localhost:1234/Instructors/2
  • 頁標題為“講師”。
  • 添加了僅在 item.OfficeAssignment 不為 null 時才顯示 item.OfficeAssignment.Location 的“辦公室”列。 由于這是一對零或一的關系,因此可能沒有相關的 OfficeAssignment 實體。HTML復制@if (item.OfficeAssignment != null) { @item.OfficeAssignment.Location }
  • 添加了顯示每位講師所授課程的“課程”列。 有關此 Razor 語法的詳細信息,請參閱使用 @: 進行顯式行轉(zhuǎn)換。
  • 添加了向所選講師的 tr 元素中動態(tài)添加 class="success" 的代碼。 此時會使用 Bootstrap 類為所選行設置背景色。HTML復制string selectedRow = ""; if (item.CourseID == Model.CourseID) { selectedRow = "success"; } <tr class="@selectedRow">
  • 添加了標記為“選擇”的新的超鏈接。 該鏈接將所選講師的 ID 發(fā)送給 Index 方法并設置背景色。HTML復制<a asp-action="Index" asp-route-id="@item.ID">Select</a> |

運行應用并選擇“講師”選項卡。該頁顯示來自相關 OfficeAssignment 實體的 Location(辦公室)。如果 OfficeAssignment` 為 NULL,則顯示空白表格單元格。

未選擇“講師索引”頁中的任何項

單擊“選擇”鏈接。 隨即更改行樣式。

添加由所選講師教授的課程

將 Pages/Instructors/Index.cshtml.cs 中的 OnGetAsync 方法替換為以下代碼:

C#

public async Task OnGetAsync(int? id, int? courseID)
{
    Instructor = new InstructorIndexData();
    Instructor.Instructors = await _context.Instructors
          .Include(i => i.OfficeAssignment)
          .Include(i => i.CourseAssignments)
            .ThenInclude(i => i.Course)
                .ThenInclude(i => i.Department)
          .AsNoTracking()
          .OrderBy(i => i.LastName)
          .ToListAsync();

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

    if (courseID != null)
    {
        CourseID = courseID.Value;
        Instructor.Enrollments = Instructor.Courses.Where(
            x => x.CourseID == courseID).Single().Enrollments;
    }
}

添加 public int CourseID { get; set; }

C#

public class IndexModel : PageModel
{
    private readonly ContosoUniversity.Data.SchoolContext _context;

    public IndexModel(ContosoUniversity.Data.SchoolContext context)
    {
        _context = context;
    }

    public InstructorIndexData Instructor { get; set; }
    public int InstructorID { get; set; }
    public int CourseID { get; set; }

    public async Task OnGetAsync(int? id, int? courseID)
    {
        Instructor = new InstructorIndexData();
        Instructor.Instructors = await _context.Instructors
              .Include(i => i.OfficeAssignment)
              .Include(i => i.CourseAssignments)
                .ThenInclude(i => i.Course)
                    .ThenInclude(i => i.Department)
              .AsNoTracking()
              .OrderBy(i => i.LastName)
              .ToListAsync();

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

        if (courseID != null)
        {
            CourseID = courseID.Value;
            Instructor.Enrollments = Instructor.Courses.Where(
                x => x.CourseID == courseID).Single().Enrollments;
        }
    }

檢查更新后的查詢:

C#

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

先前查詢添加了 Department 實體。

選擇講師時 (id != null),將執(zhí)行以下代碼。 從視圖模型中的講師列表檢索所選講師。 向視圖模型的 Courses 屬性加載來自講師 CourseAssignments 導航屬性的 Course 實體。

C#

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

Where 方法返回一個集合。 在前面的 Where 方法中,僅返回單個 Instructor 實體。 Single 方法將集合轉(zhuǎn)換為單個 Instructor 實體。 Instructor 實體提供對 CourseAssignments 屬性的訪問。 CourseAssignments 提供對相關 Course 實體的訪問。

講師-課程 m:M

當集合僅包含一個項時,集合使用 Single 方法。 如果集合為空或包含多個項,Single 方法會引發(fā)異常。 還可使用 SingleOrDefault,該方式在集合為空時返回默認值(本例中為 null)。 在空集合上使用 SingleOrDefault:

  • 引發(fā)異常(因為嘗試在空引用上找到 Courses 屬性)。
  • 異常信息不太能清楚指出問題原因。

選中課程時,視圖模型的 Enrollments 屬性將填充以下代碼:

C#

if (courseID != null)
{
    CourseID = courseID.Value;
    Instructor.Enrollments = Instructor.Courses.Where(
        x => x.CourseID == courseID).Single().Enrollments;
}

在 Pages/Instructors/Index.cshtml Razor 頁面末尾添加以下標記:

HTML

                    <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

@if (Model.Instructor.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.Instructor.Courses)
        {
            string selectedRow = "";
            if (item.CourseID == Model.CourseID)
            {
                selectedRow = "success";
            }
            <tr class="@selectedRow">
                <td>
                    <a asp-page="./Index" asp-route-courseID="@item.CourseID">Select</a>
                </td>
                <td>
                    @item.CourseID
                </td>
                <td>
                    @item.Title
                </td>
                <td>
                    @item.Department.Name
                </td>
            </tr>
        }

    </table>
}

上述標記顯示選中某講師時與該講師相關的課程列表。

測試應用。 單擊講師頁面上的“選擇”鏈接。

已選擇“講師索引”頁中的講師

顯示學生數(shù)據(jù)

在本部分中,更新應用以顯示所選課程的學生數(shù)據(jù)。

使用以下代碼在 Pages/Instructors/Index.cshtml.cs 中更新 OnGetAsync 方法中的查詢:

C#

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

更新 Pages/Instructors/Index.cshtml。 在文件末尾添加以下標記:

HTML


@if (Model.Instructor.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.Instructor.Enrollments)
        {
            <tr>
                <td>
                    @item.Student.FullName
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Grade)
                </td>
            </tr>
        }
    </table>
}

上述標記顯示已注冊所選課程的學生列表。

刷新頁面并選擇講師。 選擇一門課程,查看已注冊的學生及其成績列表。

已選擇“講師索引”頁中的講師和課程

使用 Single 方法

Single 方法可在 Where 條件中進行傳遞,無需分別調(diào)用 Where 方法:

C#

public async Task OnGetAsync(int? id, int? courseID)
{
    Instructor = new InstructorIndexData();

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

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

    if (courseID != null)
    {
        CourseID = courseID.Value;
        Instructor.Enrollments = Instructor.Courses.Single(
            x => x.CourseID == courseID).Enrollments;
    }
}

使用 Where 時,前面的 Single 方法不適用。 一些開發(fā)人員更喜歡 Single 方法樣式。

顯式加載

當前代碼為 Enrollments 和 Students 指定預先加載:

C#

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

假設用戶幾乎不希望課程中顯示注冊情況。 在此情況下,可僅在請求時加載注冊數(shù)據(jù)進行優(yōu)化。 在本部分中,會更新 OnGetAsync 以使用 Enrollments 和 Students 的顯式加載。

使用以下代碼更新 OnGetAsync:

C#

public async Task OnGetAsync(int? id, int? courseID)
{
    Instructor = new InstructorIndexData();
    Instructor.Instructors = await _context.Instructors
          .Include(i => i.OfficeAssignment)                 
          .Include(i => i.CourseAssignments)
            .ThenInclude(i => i.Course)
                .ThenInclude(i => i.Department)
            //.Include(i => i.CourseAssignments)
            //    .ThenInclude(i => i.Course)
            //        .ThenInclude(i => i.Enrollments)
            //            .ThenInclude(i => i.Student)
         // .AsNoTracking()
          .OrderBy(i => i.LastName)
          .ToListAsync();


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

    if (courseID != null)
    {
        CourseID = courseID.Value;
        var selectedCourse = Instructor.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();
        }
        Instructor.Enrollments = selectedCourse.Enrollments;
    }
}

上述代碼取消針對注冊和學生數(shù)據(jù)的 ThenInclude 方法調(diào)用。 如果已選中課程,則突出顯示的代碼會檢索:

  • 所選課程的 Enrollment 實體。
  • 每個 Enrollment 的 Student 實體。

請注意,上述代碼為 .AsNoTracking() 加上注釋。 對于跟蹤的實體,僅可顯式加載導航屬性。

測試應用。 對用戶而言,該應用的行為與上一版本相同。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號