Bagikan melalui


Tutorial: Membaca data terkait dengan EF di aplikasi MVC ASP.NET

Dalam tutorial sebelumnya Anda menyelesaikan model data Sekolah. Dalam tutorial ini Anda akan membaca dan menampilkan data terkait — yaitu, data yang dimuat Kerangka Kerja Entitas ke dalam properti navigasi.

Ilustrasi berikut ini memperlihatkan halaman yang akan Anda kerjakan.

Cuplikan layar yang memperlihatkan halaman Kursus dengan daftar kursus.

Instructors_index_page_with_instructor_and_course_selected

Unduh Proyek yang Selesai

Aplikasi web sampel Contoso University menunjukkan cara membuat aplikasi ASP.NET MVC 5 menggunakan Entity Framework 6 Code First dan Visual Studio. Untuk informasi tentang seri tutorial, lihat tutorial pertama dalam seri ini.

Di tutorial ini, Anda akan:

  • Pelajari cara memuat data terkait
  • Membuat halaman Kursus
  • Membuat halaman Instruktur

Prasyarat

Ada beberapa cara agar Kerangka Kerja Entitas dapat memuat data terkait ke dalam properti navigasi entitas:

  • Pemuatan malas. Saat entitas pertama kali dibaca, data terkait tidak diambil. Namun, pertama kali Anda mencoba mengakses properti navigasi, data yang diperlukan untuk properti navigasi tersebut diambil secara otomatis. Ini menghasilkan beberapa kueri yang dikirim ke database - satu untuk entitas itu sendiri dan satu setiap kali data terkait untuk entitas harus diambil. Kelas ini DbContext memungkinkan pemuatan malas secara default.

    Lazy_loading_example

  • Pemuatan yang bersemangat. Saat entitas dibaca, data terkait diambil bersama dengannya. Ini biasanya menghasilkan kueri gabungan tunggal yang mengambil semua data yang diperlukan. Anda menentukan pemuatan yang bersemangat dengan menggunakan Include metode .

    Eager_loading_example

  • Pemuatan eksplisit. Ini mirip dengan pemuatan malas, kecuali bahwa Anda secara eksplisit mengambil data terkait dalam kode; itu tidak terjadi secara otomatis saat Anda mengakses properti navigasi. Anda memuat data terkait secara manual dengan mendapatkan entri manajer status objek untuk entitas dan memanggil metode Collection.Load untuk koleksi atau metode Reference.Load untuk properti yang menampung satu entitas. (Dalam contoh berikut, jika Anda ingin memuat properti navigasi Administrator, Anda akan mengganti Collection(x => x.Courses) dengan Reference(x => x.Administrator).) Biasanya Anda akan menggunakan pemuatan eksplisit hanya ketika Anda telah menonaktifkan pemuatan malas.

    Explicit_loading_example

Karena tidak segera mengambil nilai properti, pemuatan malas dan pemuatan eksplisit juga keduanya dikenal sebagai pemuatan yang ditangguhkan.

Pertimbangan performa

Jika Anda tahu Bahwa Anda memerlukan data terkait untuk setiap entitas yang diambil, pemuatan yang bersemangat sering menawarkan performa terbaik, karena satu kueri yang dikirim ke database biasanya lebih efisien daripada kueri terpisah untuk setiap entitas yang diambil. Misalnya, dalam contoh di atas, misalkan setiap departemen memiliki sepuluh kursus terkait. Contoh pemuatan yang bersemangat hanya akan menghasilkan satu kueri (gabungan) dan satu perjalanan pulang pergi ke database. Contoh pemuatan malas dan pemuatan eksplisit akan menghasilkan sebelas kueri dan sebelas perjalanan pulang pergi ke database. Perjalanan pulang pergi ekstra ke database sangat merugikan performa ketika latensi tinggi.

Di sisi lain, dalam beberapa skenario pemuatan malas lebih efisien. Pemuatan bersemangat dapat menyebabkan gabungan yang sangat kompleks dihasilkan, yang SQL Server tidak dapat diproses secara efisien. Atau jika Anda perlu mengakses properti navigasi entitas hanya untuk subset dari sekumpulan entitas yang Anda proses, pemuatan malas mungkin berperforma lebih baik karena pemuatan yang bersemangat akan mengambil lebih banyak data daripada yang Anda butuhkan. Jika performa sangat penting, yang terbaik adalah menguji performa kedua cara untuk membuat pilihan terbaik.

Pemuatan malas dapat menutupi kode yang menyebabkan masalah performa. Misalnya, kode yang tidak menentukan pemuatan yang bersemangat atau eksplisit tetapi memproses entitas dalam volume tinggi dan menggunakan beberapa properti navigasi di setiap perulangan mungkin sangat tidak efisien (karena banyak perjalanan pulang pergi ke database). Aplikasi yang berkinerja baik dalam pengembangan menggunakan server SQL lokal mungkin memiliki masalah performa ketika dipindahkan ke Azure SQL Database karena peningkatan latensi dan pemuatan malas. Membuat profil kueri database dengan beban pengujian realistis akan membantu Anda menentukan apakah pemuatan malas sesuai. Untuk informasi selengkapnya, lihat Mendemystifying Entity Framework Strategies: Memuat Data Terkait dan Menggunakan Kerangka Kerja Entitas untuk Mengurangi Latensi Jaringan ke SQL Azure.

Menonaktifkan pemuatan malas sebelum serialisasi

Jika Anda membiarkan pemuatan malas diaktifkan selama serialisasi, Anda dapat akhirnya mengkueri lebih banyak data secara signifikan daripada yang Anda inginkan. Serialisasi umumnya berfungsi dengan mengakses setiap properti pada instans jenis. Akses properti memicu pemuatan malas, dan entitas yang dimuat malas tersebut diserialisasikan. Proses serialisasi kemudian mengakses setiap properti entitas yang dimuat malas, berpotensi menyebabkan pemuatan dan serialisasi yang lebih malas. Untuk mencegah reaksi rantai run-away ini, matikan pemuatan malas sebelum Anda membuat serial entitas.

Serialisasi juga dapat dipersulit oleh kelas proksi yang digunakan Kerangka Kerja Entitas, seperti yang dijelaskan dalam tutorial Skenario Tingkat Lanjut.

Salah satu cara untuk menghindari masalah serialisasi adalah dengan membuat serialisasi objek transfer data (DTO) alih-alih objek entitas, seperti yang ditunjukkan dalam tutorial Menggunakan API Web dengan Kerangka Kerja Entitas .

Jika Anda tidak menggunakan DTO, Anda dapat menonaktifkan pemuatan malas dan menghindari masalah proksi dengan menonaktifkan pembuatan proksi.

Berikut adalah beberapa cara lain untuk menonaktifkan pemuatan malas:

  • Untuk properti navigasi tertentu, hilangkan virtual kata kunci saat Anda mendeklarasikan properti .

  • Untuk semua properti navigasi, atur LazyLoadingEnabled ke false, letakkan kode berikut di konstruktor kelas konteks Anda:

    this.Configuration.LazyLoadingEnabled = false;
    

Membuat halaman Kursus

Entitas Course mencakup properti navigasi yang berisi Department entitas departemen tempat kursus ditetapkan. Untuk menampilkan nama departemen yang ditetapkan dalam daftar kursus, Anda perlu mendapatkan Name properti dari Department entitas yang ada di Course.Department properti navigasi.

Buat pengontrol bernama CourseController (bukan CoursesController) untuk Course jenis entitas, menggunakan opsi yang sama untuk Pengontrol MVC 5 dengan tampilan, menggunakan perancah Kerangka Kerja Entitas yang Anda lakukan sebelumnya untuk Student pengontrol:

Pengaturan Nilai
Kelas model Pilih Kursus (ContosoUniversity.Models).
Kelas konteks data Pilih SchoolContext (ContosoUniversity.DAL).
Nama pengontrol Masukkan CourseController. Sekali lagi, bukan CoursesController dengan s. Saat Anda memilih Kursus (ContosoUniversity.Models), nilai Nama pengontrol diisi secara otomatis. Anda harus mengubah nilainya.

Biarkan nilai default lainnya dan tambahkan pengontrol.

Buka Controllers\CourseController.cs dan lihat metodenya Index :

public ActionResult Index()
{
    var courses = db.Courses.Include(c => c.Department);
    return View(courses.ToList());
}

Perancah otomatis telah menentukan pemuatan yang bersemangat untuk Department properti navigasi dengan menggunakan Include metode .

Buka Views\Course\Index.cshtml dan ganti kode templat dengan kode berikut. Perubahan disorot:

@model IEnumerable<ContosoUniversity.Models.Course>

@{
    ViewBag.Title = "Courses";
}

<h2>Courses</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.CourseID)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Credits)
        </th>
        <th>
            Department
        </th>
        <th></th>
    </tr>

@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>
            @Html.ActionLink("Edit", "Edit", new { id=item.CourseID }) |
            @Html.ActionLink("Details", "Details", new { id=item.CourseID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.CourseID })
        </td>
    </tr>
}

</table>

Anda telah membuat perubahan berikut pada kode perancah:

  • Mengubah judul dari Indeks menjadi Kursus.
  • Menambahkan kolom Angka yang memperlihatkan CourseID nilai properti. Secara default, kunci primer tidak di-scaffold karena biasanya tidak berarti bagi pengguna akhir. Namun, dalam hal ini kunci primer bermakna dan Anda ingin menunjukkannya.
  • Memindahkan kolom Departemen ke sisi kanan dan mengubah judulnya. Perancah dengan benar memilih untuk menampilkan Name properti dari Department entitas, tetapi di sini di halaman Kursus judul kolom harus Departemen daripada Nama.

Perhatikan bahwa untuk kolom Departemen, kode perancah menampilkan Name properti Department entitas yang dimuat ke dalam Department properti navigasi:

<td>
    @Html.DisplayFor(modelItem => item.Department.Name)
</td>

Jalankan halaman (pilih tab Kursus di halaman beranda Contoso University) untuk melihat daftar dengan nama departemen.

Membuat halaman Instruktur

Di bagian ini Anda akan membuat pengontrol dan menampilkan entitas Instructor untuk menampilkan halaman Instruktur. Halaman ini membaca dan menampilkan data terkait dengan cara berikut:

  • Daftar instruktur menampilkan data terkait dari OfficeAssignment entitas. Entitas Instructor dan OfficeAssignment berada dalam hubungan satu-ke-nol-atau-satu. Anda akan menggunakan pemuatan yang bersemangat untuk OfficeAssignment entitas. Seperti yang dijelaskan sebelumnya, pemuatan yang bersemangat biasanya lebih efisien ketika Anda memerlukan data terkait untuk semua baris tabel utama yang diambil. Dalam hal ini, Anda ingin menampilkan tugas kantor untuk semua instruktur yang ditampilkan.
  • Saat pengguna memilih instruktur, entitas terkait Course ditampilkan. Entitas Instructor dan Course berada dalam hubungan banyak ke banyak. Anda akan menggunakan pemuatan yang bersemangat untuk Course entitas dan entitas terkaitnya Department . Dalam hal ini, pemuatan malas mungkin lebih efisien karena Anda hanya memerlukan kursus untuk instruktur yang dipilih. Namun, contoh ini menunjukkan cara menggunakan pemuatan yang bersemangat untuk properti navigasi dalam entitas yang berada di properti navigasi.
  • Saat pengguna memilih kursus, data terkait dari Enrollments kumpulan entitas ditampilkan. Entitas Course dan Enrollment berada dalam hubungan satu-ke-banyak. Anda akan menambahkan pemuatan eksplisit untuk Enrollment entitas dan entitas terkaitnya Student . (Pemuatan eksplisit tidak diperlukan karena pemuatan malas diaktifkan, tetapi ini menunjukkan cara melakukan pemuatan eksplisit.)

Membuat Model Tampilan untuk Tampilan Indeks Instruktur

Halaman Instruktur memperlihatkan tiga tabel berbeda. Oleh karena itu, Anda akan membuat model tampilan yang menyertakan tiga properti, masing-masing menyimpan data untuk salah satu tabel.

Di folder ViewModels , buat InstructorIndexData.cs dan ganti kode yang ada dengan kode berikut:

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; }
    }
}

Membuat Pengontrol dan Tampilan Instruktur

InstructorController Buat pengontrol (bukan InstructorsController) dengan tindakan baca/tulis EF:

Pengaturan Nilai
Kelas model Pilih Instruktur (ContosoUniversity.Models).
Kelas konteks data Pilih SchoolContext (ContosoUniversity.DAL).
Nama pengontrol Masukkan InstructorController. Sekali lagi, bukan InstrukturKontrol dengan s. Saat Anda memilih Kursus (ContosoUniversity.Models), nilai Nama pengontrol diisi secara otomatis. Anda harus mengubah nilainya.

Biarkan nilai default lainnya dan tambahkan pengontrol.

Buka Controllers\InstructorController.cs dan tambahkan using pernyataan untuk ViewModels namespace:

using ContosoUniversity.ViewModels;

Kode perancah dalam Index metode menentukan pemuatan yang bersemangat hanya untuk OfficeAssignment properti navigasi:

public ActionResult Index()
{
    var instructors = db.Instructors.Include(i => i.OfficeAssignment);
    return View(instructors.ToList());
}

Index Ganti metode dengan kode berikut untuk memuat data terkait tambahan dan memasukkannya ke dalam model tampilan:

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.ID == 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);
}

Metode ini menerima data rute opsional (id) dan parameter string kueri (courseID) yang menyediakan nilai ID dari instruktur yang dipilih dan kursus yang dipilih, dan meneruskan semua data yang diperlukan ke tampilan. Parameter disediakan oleh Pilih hyperlink di halaman.

Kode dimulai dengan membuat instans model tampilan dan memasukkan daftar instruktur di dalamnya. Kode menentukan pemuatan yang bersemangat untuk Instructor.OfficeAssignment properti navigasi dan Instructor.Courses .

var viewModel = new InstructorIndexData();
viewModel.Instructors = db.Instructors
    .Include(i => i.OfficeAssignment)
    .Include(i => i.Courses.Select(c => c.Department))
     .OrderBy(i => i.LastName);

Metode kedua Include memuat Kursus, dan untuk setiap Kursus yang dimuat itu tidak ingin memuat untuk Course.Department properti navigasi.

.Include(i => i.Courses.Select(c => c.Department))

Seperti disebutkan sebelumnya, pemuatan yang bersemangat tidak diperlukan tetapi dilakukan untuk meningkatkan performa. Karena tampilan selalu memerlukan OfficeAssignment entitas, lebih efisien untuk mengambilnya dalam kueri yang sama. Course entitas diperlukan ketika instruktur dipilih di halaman web, sehingga pemuatan yang bersemangat lebih baik daripada pemuatan malas hanya jika halaman ditampilkan lebih sering dengan kursus yang dipilih daripada tanpa.

Jika ID instruktur dipilih, instruktur yang dipilih diambil dari daftar instruktur dalam model tampilan. Properti model Courses tampilan kemudian dimuat dengan Course entitas dari properti navigasi instruktur tersebut Courses .

if (id != null)
{
    ViewBag.InstructorID = id.Value;
    viewModel.Courses = viewModel.Instructors.Where(i => i.ID == id.Value).Single().Courses;
}

Metode mengembalikan Where koleksi, tetapi dalam hal ini kriteria yang diteruskan ke metode tersebut hanya menghasilkan satu Instructor entitas yang dikembalikan. Metode ini Single mengonversi koleksi menjadi satu Instructor entitas, yang memberi Anda akses ke properti entitas tersebut Courses .

Anda menggunakan metode Tunggal pada koleksi ketika Anda tahu koleksi hanya akan memiliki satu item. Metode Single ini memberikan pengecualian jika koleksi yang diteruskan ke dalamnya kosong atau jika ada lebih dari satu item. Alternatifnya adalah SingleOrDefault, yang mengembalikan nilai default (null dalam hal ini) jika koleksi kosong. Namun, dalam hal ini yang masih akan menghasilkan pengecualian (dari mencoba menemukan Courses properti pada null referensi), dan pesan pengecualian akan kurang jelas menunjukkan penyebab masalah. Ketika Anda memanggil Single metode , Anda juga dapat meneruskan Where kondisi alih-alih memanggil Where metode secara terpisah:

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

Alih-alih:

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

Selanjutnya, jika kursus dipilih, kursus yang dipilih diambil dari daftar kursus dalam model tampilan. Kemudian properti model Enrollments tampilan dimuat dengan Enrollment entitas dari properti navigasi kursus tersebut Enrollments .

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

Mengubah Tampilan Indeks Instruktur

Di Views\Instructor\Index.cshtml, ganti kode templat dengan kode berikut. Perubahan disorot:

@model ContosoUniversity.ViewModels.InstructorIndexData

@{
    ViewBag.Title = "Instructors";
}

<h2>Instructors</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>Last Name</th>
        <th>First Name</th>
        <th>Hire Date</th>
        <th>Office</th>
        <th></th>
    </tr>

    @foreach (var item in Model.Instructors)
    {
        string selectedRow = "";
        if (item.ID == ViewBag.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>
                @Html.ActionLink("Select", "Index", new { id = item.ID }) |
                @Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
                @Html.ActionLink("Details", "Details", new { id = item.ID }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.ID })
            </td>
        </tr>
    }

    </table>

Anda telah membuat perubahan berikut pada kode yang ada:

  • Mengubah kelas model menjadi InstructorIndexData.

  • Mengubah judul halaman dari Indeks menjadi Instruktur.

  • Menambahkan kolom Office yang hanya ditampilkan item.OfficeAssignment.Location jika item.OfficeAssignment tidak null. (Karena ini adalah hubungan satu-ke-nol atau satu, mungkin tidak ada entitas terkait OfficeAssignment .)

    <td> 
        @if (item.OfficeAssignment != null) 
        { 
            @item.OfficeAssignment.Location  
        } 
    </td>
    
  • Menambahkan kode yang akan secara dinamis ditambahkan class="success" ke tr elemen instruktur yang dipilih. Ini mengatur warna latar belakang untuk baris yang dipilih menggunakan kelas Bootstrap .

    string selectedRow = ""; 
    if (item.InstructorID == ViewBag.InstructorID) 
    { 
        selectedRow = "success"; 
    } 
    <tr class="@selectedRow" valign="top">
    
  • Menambahkan label baru ActionLinkPilih segera sebelum tautan lain di setiap baris, yang menyebabkan ID instruktur yang dipilih dikirim ke Index metode .

Jalankan aplikasi dan pilih tab Instruktur . Halaman menampilkan Location properti entitas terkait OfficeAssignment dan sel tabel kosong saat tidak ada entitas terkait OfficeAssignment .

Dalam file Views\Instructor\Index.cshtml , setelah elemen penutup table (di akhir file), tambahkan kode berikut. Kode ini menampilkan daftar kursus yang terkait dengan instruktur saat instruktur dipilih.

@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 == ViewBag.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>
}

Kode ini membaca Courses properti model tampilan untuk menampilkan daftar kursus. Ini juga menyediakan Select hyperlink yang mengirim ID kursus yang dipilih ke Index metode tindakan.

Jalankan halaman dan pilih instruktur. Sekarang Anda melihat kisi yang menampilkan kursus yang ditetapkan ke instruktur yang dipilih, dan untuk setiap kursus Anda melihat nama departemen yang ditetapkan.

Setelah blok kode yang baru saja Anda tambahkan, tambahkan kode berikut. Ini menampilkan daftar siswa yang terdaftar dalam kursus ketika kursus tersebut dipilih.

@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>
}

Kode ini membaca Enrollments properti model tampilan untuk menampilkan daftar siswa yang terdaftar dalam kursus.

Jalankan halaman dan pilih instruktur. Kemudian pilih kursus untuk melihat daftar siswa terdaftar dan nilai mereka.

Menambahkan Pemuatan Eksplisit

Buka InstructorController.cs dan lihat bagaimana Index metode mendapatkan daftar pendaftaran untuk kursus yang dipilih:

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

Ketika Anda mengambil daftar instruktur, Anda menentukan pemuatan yang bersemangat untuk Courses properti navigasi dan untuk Department properti dari setiap kursus. Kemudian Anda meletakkan Courses koleksi dalam model tampilan, dan sekarang Anda mengakses properti navigasi dari satu entitas dalam koleksi tersebut Enrollments . Karena Anda tidak menentukan pemuatan yang ingin dimuat untuk Course.Enrollments properti navigasi, data dari properti tersebut muncul di halaman sebagai akibat dari pemuatan malas.

Jika Anda menonaktifkan pemuatan malas tanpa mengubah kode dengan cara lain, Enrollments properti akan null terlepas dari berapa banyak pendaftaran yang sebenarnya dimiliki kursus. Dalam hal ini, untuk memuat Enrollments properti , Anda harus menentukan pemuatan yang bersemangat atau pemuatan eksplisit. Anda sudah melihat cara melakukan pemuatan yang bersemangat. Untuk melihat contoh pemuatan eksplisit, ganti Index metode dengan kode berikut, yang secara eksplisit memuat Enrollments properti . Kode yang diubah disorot.

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.ID == id.Value).Single().Courses;
    }
    
    if (courseID != null)
    {
        ViewBag.CourseID = courseID.Value;
        // Lazy loading
        //viewModel.Enrollments = viewModel.Courses.Where(
        //    x => x.CourseID == courseID).Single().Enrollments;
        // Explicit loading
        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);
}

Setelah mendapatkan entitas yang dipilih Course , kode baru secara eksplisit memuat properti navigasi kursus tersebut Enrollments :

db.Entry(selectedCourse).Collection(x => x.Enrollments).Load();

Kemudian secara eksplisit memuat entitas terkait Student masing-masing Enrollment entitas:

db.Entry(enrollment).Reference(x => x.Student).Load();

Perhatikan bahwa Anda menggunakan Collection metode untuk memuat properti koleksi, tetapi untuk properti yang hanya menyimpan satu entitas, Anda menggunakan metode .Reference

Jalankan halaman Indeks Instruktur sekarang dan Anda tidak akan melihat perbedaan apa yang ditampilkan di halaman, meskipun Anda telah mengubah cara data diambil.

Mendapatkan kode

Unduh Proyek yang Selesai

Sumber Daya Tambahan:

Tautan ke sumber daya Kerangka Kerja Entitas lainnya dapat ditemukan di Akses Data ASP.NET - Sumber Daya yang Direkomendasikan.

Langkah berikutnya

Di tutorial ini, Anda akan:

  • Mempelajari cara memuat data terkait
  • Membuat halaman Kursus
  • Membuat halaman Instruktur

Lanjutkan ke artikel berikutnya untuk mempelajari cara memperbarui data terkait.