Öğretici: İlgili verileri okuma - ile MVC ASP.NET EF Core
Önceki öğreticide School veri modelini tamamladınız. Bu öğreticide, Entity Framework'ün gezinti özelliklerine yüklemiş olduğu verileri okuyacak ve görüntüleyeceksiniz.
Aşağıdaki çizimlerde birlikte çalışacağınız sayfalar gösterilmektedir.
Bu öğreticide şunları yaptınız:
- İlgili verileri yüklemeyi öğrenin
- Kurslar sayfası oluşturma
- Eğitmenler sayfası oluşturma
- Açık yükleme hakkında bilgi edinin
Ön koşullar
İlgili verileri yüklemeyi öğrenin
Entity Framework gibi Nesne İlişkisel Eşleme (ORM) yazılımının ilgili verileri bir varlığın gezinti özelliklerine yüklemesinin çeşitli yolları vardır:
İstekli yükleme: Varlık okunduğunda, onunla birlikte ilgili veriler de alınır. Bu genellikle gereken tüm verileri alan tek bir birleştirme sorgusuyla sonuçlanmıştır. ve
ThenInclude
yöntemlerini kullanarakInclude
Entity Framework Core'da hevesle yüklemeyi belirtirsiniz.Verilerin bazılarını ayrı sorgularda alabilirsiniz ve EF gezinti özelliklerini "düzeltir". Yani EF, daha önce alınan varlıkların gezinti özelliklerine ait oldukları ayrı olarak alınan varlıkları otomatik olarak ekler. İlgili verileri alan sorgu için, veya gibi
ToList
Single
bir liste veya nesne döndüren bir yöntem yerine yöntemini kullanabilirsinizLoad
.Açık yükleme: Varlık ilk okunduğunda ilgili veriler alınmaz. Gerekirse ilgili verileri alan kod yazarsınız. Ayrı sorgularla hevesle yükleme durumunda olduğu gibi açıkça yükleme, veritabanına gönderilen birden çok sorguya neden olur. Aradaki fark, açık yükleme ile kodun yüklenecek gezinti özelliklerini belirtmesidir. Entity Framework Core 1.1'de yöntemini kullanarak
Load
açık yükleme yapabilirsiniz. Örnek:Gecikmeli yükleme: Varlık ilk okunduğunda ilgili veriler alınmaz. Ancak, bir gezinti özelliğine ilk kez erişmeye çalıştığınızda, bu gezinti özelliği için gereken veriler otomatik olarak alınır. Bir gezinti özelliğinden ilk kez veri almaya çalıştığınızda veritabanına bir sorgu gönderilir. Entity Framework Core 1.0 gecikmeli yüklemeyi desteklemez.
Performansla ilgili önemli noktalar
Alınan her varlık için ilgili verilere ihtiyacınız olduğunu biliyorsanız, veritabanına gönderilen tek bir sorgu genellikle alınan her varlık için ayrı sorgulardan daha verimli olduğundan, istekli yükleme genellikle en iyi performansı sunar. Örneğin, her bölümün on ilgili kursu olduğunu varsayalım. Tüm ilgili verilerin hevesle yüklenmesi tek bir (birleştirme) sorgusuna ve veritabanına tek bir gidiş dönüşe neden olur. Her bölüm için ayrı bir kurs sorgusu veritabanına on bir gidiş dönüşle sonuçlanır. Veritabanına fazladan gidiş dönüşler, özellikle gecikme süresi yüksek olduğunda performansa zarar verebilirsiniz.
Öte yandan bazı senaryolarda ayrı sorgular daha verimlidir. Tüm ilgili verilerin tek bir sorguya hevesle yüklenmesi, SQL Server'ın verimli bir şekilde işleyebildiği çok karmaşık bir birleştirme oluşturulmasına neden olabilir. Öte yandan, bir varlığın gezinti özelliklerine yalnızca işlemekte olduğunuz varlık kümesinin bir alt kümesi için erişmeniz gerekiyorsa, her şeyin önden hızlı yüklenmesi gerekenden daha fazla veri alacağından ayrı sorgular daha iyi performans gösterebilir. Performans kritikse, en iyi seçimi yapmak için performansı her iki yolla da test etmek en iyisidir.
Kurslar sayfası oluşturma
Varlık, Course
kursun Department
atandığı bölümün varlığını içeren bir gezinti özelliği içerir. Atanan bölümün adını bir kurs listesinde görüntülemek için, özelliği gezinti özelliğindeki Course.Department
varlıktan Department
almanız Name
gerekir.
Aşağıdaki çizimde Course
gösterildiği gibi, daha önce için yaptığınız Entity Framework iskelesini kullanarak görünümlere sahip MVC Denetleyicisi için aynı seçenekleri kullanarak varlık türü için StudentsController
adlı CoursesController
bir denetleyici oluşturun:
yöntemini açın CoursesController.cs
ve inceleyin Index
. Otomatik iskele, yöntemini kullanarak gezinti özelliği için Department
istekli yükleme belirtti Include
.
Index
yöntemini, Course varlıklarını döndürencourses
(yerineschoolContext
) için IQueryable
daha uygun bir ad kullanan aşağıdaki kodla değiştirin:
public async Task<IActionResult> Index()
{
var courses = _context.Courses
.Include(c => c.Department)
.AsNoTracking();
return View(await courses.ToListAsync());
}
Şablon kodunu açın Views/Courses/Index.cshtml
ve aşağıdaki kodla değiştirin. Değişiklikler vurgulanır:
@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>
yapı iskelesi oluşturulmuş kodda aşağıdaki değişiklikleri yaptınız:
Dizin başlığı Kurslar olarak değiştirildi.
Özellik değerini gösteren
CourseID
bir Sayı sütunu eklendi. Varsayılan olarak, birincil anahtarlar son kullanıcılar için anlamlı olmadığından yapı iskelesi oluşturmaz. Ancak, bu durumda birincil anahtar anlamlıdır ve bunu göstermek istiyorsunuz.Departman adını görüntülemek için Department sütunu değiştirildi. Kod, gezinti özelliğine
Department
yüklenen varlığınDepartment
özelliğini görüntülerName
:@Html.DisplayFor(modelItem => item.Department.Name)
Uygulamayı çalıştırın ve bölüm adlarını içeren listeyi görmek için Kurslar sekmesini seçin.
Eğitmenler sayfası oluşturma
Bu bölümde, Eğitmenler sayfasını görüntülemek için varlık için Instructor
bir denetleyici ve görünüm oluşturacaksınız:
Bu sayfa, ilgili verileri aşağıdaki yollarla okur ve görüntüler:
Eğitmenler listesinde varlıkla
OfficeAssignment
ilgili veriler görüntülenir.Instructor
veOfficeAssignment
varlıkları bire sıfıra veya bir ilişkisindedir. Varlıklar için hevesleOfficeAssignment
yüklemeyi kullanacaksınız. Daha önce açıklandığı gibi, birincil tablonun tüm alınan satırları için ilgili verilere ihtiyacınız olduğunda, istekli yükleme genellikle daha verimlidir. Bu durumda, görüntülenen tüm eğitmenler için ofis ödevlerini görüntülemek istiyorsunuz.Kullanıcı bir eğitmen seçtiğinde ilgili
Course
varlıklar görüntülenir.Instructor
veCourse
varlıkları çoka çok ilişkisindedir. Varlıklar ve ilgiliDepartment
varlıklar içinCourse
hızlı yükleme kullanacaksınız. Bu durumda, yalnızca seçilen eğitmen için kurslara ihtiyacınız olduğundan ayrı sorgular daha verimli olabilir. Ancak bu örnekte, gezinti özelliklerinde kendileri olan varlıklardaki gezinti özellikleri için hevesle yüklemenin nasıl kullanılacağı gösterilmektedir.Kullanıcı bir kurs seçtiğinde varlık kümesindeki
Enrollments
ilgili veriler görüntülenir.Course
veEnrollment
varlıkları bire çok ilişkisindedir. Varlıklar ve bunların ilgiliStudent
varlıkları içinEnrollment
ayrı sorgular kullanacaksınız.
Eğitmen Dizini görünümü için görünüm modeli oluşturma
Eğitmenler sayfasında üç farklı tablodaki veriler gösterilir. Bu nedenle, her biri tablolardan birine ait verileri tutan üç özellik içeren bir görünüm modeli oluşturacaksınız.
SchoolViewModels klasöründe mevcut kodu oluşturun InstructorIndexData.cs
ve aşağıdaki kodla değiştirin:
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; }
}
}
Eğitmen denetleyicisini ve görünümlerini oluşturma
Aşağıdaki çizimde gösterildiği gibi EF okuma/yazma eylemleriyle eğitmen denetleyicisi oluşturun:
ViewModels ad alanı için bir using deyimi açın InstructorsController.cs
ve ekleyin:
using ContosoUniversity.Models.SchoolViewModels;
İlgili verilerin hevesle yüklenmesini sağlamak ve görünüm modeline yerleştirmek için Index yöntemini aşağıdaki kodla değiştirin.
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);
}
yöntemi, seçilen eğitmenin ve seçilen kursun kimlik değerlerini sağlayan isteğe bağlı yol verileriniid
() ve bir sorgu dizesi parametresini (courseID
) kabul eder. Parametreler, sayfadaki Köprüleri seçin tarafından sağlanır.
Kod, görünüm modelinin bir örneğini oluşturup eğitmen listesine ekleyerek başlar. Kod, ve gezinti özellikleri için Instructor.OfficeAssignment
hevesle Instructor.CourseAssignments
yüklemeyi belirtir. CourseAssignments
özelliği içinde Course
özelliği yüklenir ve bu Enrollments
özellik içinde ve Department
özellikleri yüklenir ve her Enrollment
varlık Student
içinde özelliği yüklenir.
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();
Görünüm her zaman varlığı gerektirdiğinden OfficeAssignment
, bunu aynı sorguya getirmek daha verimlidir. Web sayfasında bir eğitmen seçildiğinde kurs varlıkları gereklidir, bu nedenle tek bir sorgu birden çok sorgudan daha iyidir, ancak sayfa bir kurs seçilmeden daha sık görüntüleniyorsa.
kodu yineler CourseAssignments
ve Course
'den Course
iki özelliğe ihtiyacınız olduğundan. İlk çağrı dizesi ThenInclude
, Course.Enrollments
ve Enrollment.Student
alırCourseAssignment.Course
.
Birden çok ilişkili veri düzeyi dahil olmak üzere daha fazla bilgiyi burada okuyabilirsiniz.
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();
Kodun bu noktasında, başka bir diğeri ThenInclude
, ihtiyacınız olmayan gezinti özellikleri Student
içindir. Ancak arama Include
özellikleriyle Instructor
başlar, bu nedenle zincirden tekrar geçmeniz gerekir; bu kez yerine Course.Enrollments
belirterekCourse.Department
.
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();
Eğitmen seçildiğinde aşağıdaki kod yürütülür. Seçilen eğitmen, görünüm modelindeki eğitmenler listesinden alınır. Görünüm modelinin Courses
özelliği daha sonra bu eğitmenin Course
CourseAssignments
gezinti özelliğindeki varlıklarla birlikte yüklenir.
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
yöntemi bir koleksiyon döndürür, ancak bu durumda bu yönteme geçirilen ölçütler yalnızca tek bir Eğitmen varlığı döndürülür. yöntemi, Single
koleksiyonu tek Instructor
bir varlığa dönüştürür ve bu sayede bu varlığın CourseAssignments
özelliğine erişmenizi sağlar. CourseAssignments
özelliği, yalnızca ilgili Course
varlıkları istediğiniz varlıkları içerirCourseAssignment
.
Bir koleksiyonda Single
yöntemini, koleksiyonun yalnızca bir öğeye sahip olacağını bildiğinizde kullanırsınız. yöntemi, Single
geçirilen koleksiyon boşsa veya birden fazla öğe varsa bir özel durum oluşturur. Alternatif olarak SingleOrDefault
, koleksiyon boşsa varsayılan bir değer (bu örnekte null) döndürür. Ancak, bu durumda yine de bir özel durumla sonuçlanır (null başvuruda bir Courses
özelliği bulmaya çalışırken) ve özel durum iletisi sorunun nedenini daha az net bir şekilde gösterir. yöntemini çağırdığınızda Single
, yöntemini ayrı olarak çağırmak yerine Where koşulunu Where
da geçirebilirsiniz:
.Single(i => i.ID == id.Value)
Aşağıdaki değer yerine:
.Where(i => i.ID == id.Value).Single()
Ardından, bir kurs seçildiyse, seçilen kurs görünüm modelindeki kurs listesinden alınır. Ardından görünüm modelinin Enrollments
özelliği, bu kursun Enrollments
gezinti özelliğinden Kayıt varlıklarıyla yüklenir.
if (courseID != null)
{
ViewData["CourseID"] = courseID.Value;
viewModel.Enrollments = viewModel.Courses.Where(
x => x.CourseID == courseID).Single().Enrollments;
}
İzleme ve izleme yok karşılaştırması
İzlemesiz sorgular, sonuçlar salt okunur bir senaryoda kullanıldığında kullanışlıdır. Değişiklik izleme bilgilerini ayarlamaya gerek olmadığından, bunlar genellikle daha hızlı yürütülür. Veritabanından alınan varlıkların güncelleştirilmiş olması gerekmiyorsa, izleme sorgusunun izleme sorgusundan daha iyi performans gösterme olasılığı yüksektir.
Bazı durumlarda izleme sorgusu, izleme olmayan sorgudan daha verimlidir. Daha fazla bilgi için bkz . İzleme ve İzleme Olmayan Sorgular.
Eğitmen Dizini görünümünü değiştirme
içinde Views/Instructors/Index.cshtml
şablon kodunu aşağıdaki kodla değiştirin. Değişiklikler vurgulanır.
@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 = "table-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>
@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>
Mevcut kodda aşağıdaki değişiklikleri yaptınız:
Model sınıfı olarak
InstructorIndexData
değiştirildi.Sayfa başlığı Dizinden Eğitmenlere değiştirildi.
Yalnızca
item.OfficeAssignment
null değilse görüntülenenitem.OfficeAssignment.Location
bir Office sütunu eklendi. (Bu bire sıfıra veya bir ilişkisi olduğundan, ilgili bir OfficeAssignment varlığı olmayabilir.)@if (item.OfficeAssignment != null) { @item.OfficeAssignment.Location }
Her eğitmen tarafından öğretilen kursları görüntüleyen bir Kurslar sütunu eklendi. Daha fazla bilgi için söz dizimi makalesinin Razor Açık satır geçişi bölümüne bakın.
Seçili eğitmenin öğesine koşullu olarak bir Bootstrap CSS sınıfı
tr
ekleyen kod eklendi. Bu sınıf, seçili satır için bir arka plan rengi ayarlar.Her satırdaki diğer bağlantılardan hemen önce seç etiketli yeni bir köprü eklendi ve bu da seçilen eğitmenin kimliğinin
Index
yönteme gönderilmesine neden oluyor.<a asp-action="Index" asp-route-id="@item.ID">Select</a> |
Uygulamayı çalıştırın ve Eğitmenler sekmesini seçin. Sayfa, ilgili OfficeAssignment varlıklarının Location özelliğini ve ilgili OfficeAssignment varlığı olmadığında boş bir tablo hücresini görüntüler.
Views/Instructors/Index.cshtml
dosyasında, kapanış tablosu öğesinden sonra (dosyanın sonuna), aşağıdaki kodu ekleyin. Bu kod, eğitmen seçildiğinde eğitmenle ilgili derslerin listesini görüntüler.
@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>
}
Bu kod, kurs listesini görüntülemek için görünüm modelinin özelliğini okur Courses
. Ayrıca seçili kursun kimliğini eylem yöntemine Index
gönderen Bir Seç köprüsü sağlar.
Sayfayı yenileyin ve bir eğitmen seçin. Artık seçili eğitmene atanmış olan dersleri görüntüleyen bir kılavuz görürsünüz ve her kurs için atanan bölümün adını görürsünüz.
Yeni eklediğiniz kod bloğundan sonra aşağıdaki kodu ekleyin. Bu, o kurs seçildiğinde bir kursa kayıtlı olan öğrencilerin listesini görüntüler.
@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>
}
Bu kod, kursa Enrollments
kayıtlı öğrencilerin listesini görüntülemek için görünüm modelinin özelliğini okur.
Sayfayı yeniden yenileyin ve bir eğitmen seçin. Ardından, kayıtlı öğrencilerin listesini ve notlarını görmek için bir kurs seçin.
Açık yükleme hakkında
içindeki InstructorsController.cs
eğitmenlerin listesini aldığınızda gezinti özelliği için istekli yükleme belirttiniz CourseAssignments
.
Kullanıcıların yalnızca seçilen eğitmen ve kurstaki kayıtları nadiren görmek istemesini beklediğinizi varsayalım. Bu durumda, kayıt verilerini yalnızca istenirse yüklemek isteyebilirsiniz. Açık yüklemenin nasıl yapıldığını gösteren bir örnek görmek için yöntemini aşağıdaki kodla değiştirin Index
. Bu kod, bu özelliğin hevesle yüklenmesini Enrollments
kaldırır ve bu özelliği açıkça yükler. Kod değişiklikleri vurgulanır.
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);
}
Yeni kod, eğitmen varlıklarını alan koddan kayıt verilerine yönelik yöntem çağrılarını bırakır ThenInclude
. Ayrıca düşer AsNoTracking
. Eğitmen ve kurs seçilirse, vurgulanan kod seçilen kursun varlıklarını Enrollment
ve Student
her Enrollment
biri için varlıkları alır.
Uygulamayı çalıştırın, eğitmen dizini sayfasına gidin ve verilerin nasıl alındığını değiştirmiş olmanıza rağmen sayfada görüntülenenler arasında hiçbir fark görmezsiniz.
Kodu alma
Tamamlanan uygulamayı indirin veya görüntüleyin.
Sonraki adımlar
Bu öğreticide şunları yaptınız:
- İlgili verileri yüklemeyi öğrenme
- Kurslar sayfası oluşturuldu
- Eğitmenler sayfası oluşturuldu
- Açık yükleme hakkında bilgi edinildi
İlgili verileri nasıl güncelleştireceğinizi öğrenmek için sonraki öğreticiye geçin.
ASP.NET Core