Öğretici: ASP.NET MVC uygulamasında EF ile ilgili verileri okuma
Önceki öğreticide School veri modelini tamamladınız. Bu öğreticide ilgili verileri ( yani Entity Framework'ün gezinti özelliklerine yüklediğini) okuyacak ve görüntüleyeceksiniz.
Aşağıdaki çizimlerde, çalışacağınız sayfalar gösterilmektedir.
Contoso University örnek web uygulaması, Entity Framework 6 Code First ve Visual Studio kullanarak ASP.NET MVC 5 uygulamalarının nasıl oluşturulacağını gösterir. Öğretici serisi hakkında bilgi için serideki ilk öğreticiye bakın.
Bu öğreticide şunları yaptınız:
- İlgili verileri yüklemeyi öğrenin
- Kurslar sayfası oluşturma
- Eğitmenler sayfası oluşturma
Önkoşullar
İlgili verileri yüklemeyi öğrenin
Entity Framework'ün ilgili verileri bir varlığın gezinti özelliklerine yüklemesinin çeşitli yolları vardır:
Yavaş 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. Bu, veritabanına birden çok sorgu gönderilmesiyle sonuçlanır. Bunlardan biri varlığın kendisi için, diğeri de varlıkla ilgili verilerin her alınması gerektiğinde alınır.
DbContext
sınıfı varsayılan olarak gecikmeli yüklemeyi etkinleştirir.İ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. yöntemini kullanarak
Include
istekli yükleme belirtirsiniz.Açık yükleme. Bu, koddaki ilgili verileri açıkça almanız dışında gecikmeli yüklemeye benzer; bir gezinti özelliğine eriştiğinde otomatik olarak gerçekleşmez. Bir varlığın nesne durumu yöneticisi girdisini alıp koleksiyonlar için Collection.Load yöntemini veya tek bir varlığı barındıran özellikler için Reference.Load yöntemini çağırarak ilgili verileri el ile yüklersiniz. (Aşağıdaki örnekte, Yönetici gezinti özelliğini yüklemek isterseniz değerini ile
Reference(x => x.Administrator)
değiştirirsinizCollection(x => x.Courses)
.) Genellikle açık yüklemeyi yalnızca gecikmeli yüklemeyi kapattığınızda kullanırsınız.
Özellik değerlerini hemen almadıkları için gecikmeli yükleme ve açık yükleme de ertelenmiş yükleme olarak bilinir.
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, yukarıdaki örneklerde her departmanın on ilgili kursu olduğunu varsayalım. İstekli yükleme örneği yalnızca tek bir (birleştirme) sorgusuna ve veritabanına tek bir gidiş dönüşe neden olur. Yavaş yükleme ve açık yükleme örnekleri hem on bir sorguya hem de veritabanına on bir gidiş dönüşe neden olur. Veritabanına yapılan ek gidiş dönüşler, özellikle gecikme süresi yüksek olduğunda performansa zarar vericidir.
Öte yandan, bazı senaryolarda gecikmeli yükleme daha verimlidir. Hızlı yükleme, çok karmaşık bir birleştirmenin oluşturulmasına neden olabilir ve SQL Server verimli bir şekilde işlem yapamaz. Ö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, istekli yükleme ihtiyacınızdan daha fazla veri alacağından gecikmeli yükleme daha iyi performans gösterebilir. Performans kritikse, en iyi seçimi yapmak için performansı her iki yolla da test etmek en iyisidir.
Yavaş yükleme, performans sorunlarına neden olan kodu maskeleyebilir. Örneğin, istekli veya açık yükleme belirtmeyen ancak yüksek hacimli varlıkları işleyen ve her yinelemede çeşitli gezinti özellikleri kullanan kod çok verimsiz olabilir (veritabanına yapılan birçok gidiş dönüş nedeniyle). Şirket içi SQL sunucusu kullanarak geliştirme aşamasında iyi performans gösteren bir uygulama, artan gecikme süresi ve gecikmeli yükleme nedeniyle Azure SQL Veritabanına taşındığında performans sorunları yaşayabilir. Gerçekçi bir test yüküyle veritabanı sorgularının profilini oluşturmak gecikmeli yüklemenin uygun olup olmadığını belirlemenize yardımcı olur. Daha fazla bilgi için bkz. Entity Framework Stratejilerini Kaldırma: İlgili Verileri Yükleme ve Ağ Gecikme süresini azaltmak için Entity Framework'ün SQL Azure kullanma.
Serileştirmeden önce gecikmeli yüklemeyi devre dışı bırakma
Serileştirme sırasında gecikmeli yüklemeyi etkin bırakırsanız, istediğinizden çok daha fazla veriyi sorgulayabilirsiniz. Serileştirme genellikle türün bir örneğindeki her özelliğe erişerek çalışır. Özellik erişimi gecikmeli yüklemeyi tetikler ve bu gecikmeli yüklenen varlıklar seri hale getirilir. Serileştirme işlemi daha sonra gecikmeli yüklenen varlıkların her özelliğine erişerek daha da gecikmeli yükleme ve serileştirmeye neden olur. Bu kaçma zinciri tepkisini önlemek için, bir varlığı seri hale getirmeden önce gecikmeli yüklemeyi kapatın.
Serileştirme, Gelişmiş Senaryolar öğreticisinde açıklandığı gibi Entity Framework'ün kullandığı ara sunucu sınıfları tarafından da karmaşık olabilir.
Entity Framework ile Web API'sini Kullanma öğreticisinde gösterildiği gibi, serileştirme sorunlarını önlemenin bir yolu varlık nesneleri yerine veri aktarımı nesnelerini (DTO' lar) seri hale getirmektir.
DTO'ları kullanmıyorsanız, ara sunucu oluşturmayı devre dışı bırakarak gecikmeli yüklemeyi devre dışı bırakabilir ve ara sunucu sorunlarını önleyebilirsiniz.
Yavaş yüklemeyi devre dışı bırakmanın diğer bazı yolları şunlardır:
Belirli gezinti özellikleri için, özelliğini bildirirken anahtar sözcüğünü atlar
virtual
.Tüm gezinti özellikleri için
false
olarak ayarlayınLazyLoadingEnabled
ve bağlam sınıfınızın oluşturucusunda aşağıdaki kodu yerleştirin:this.Configuration.LazyLoadingEnabled = false;
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, gezinti özelliğindeki Course.Department
varlıktan Department
özelliğini almanız Name
gerekir.
Daha önce denetleyici için yaptığınız Entity Framework iskelesini Course
kullanarak, görünümlere sahip MVC 5 Denetleyicisi için aynı seçenekleri kullanarak varlık türü için Student
(CoursesController değil) adlı CourseController
bir denetleyici oluşturun:
Ayar | Değer |
---|---|
Model sınıfı | Kurs (ContosoUniversity.Models) öğesini seçin. |
Veri bağlamı sınıfı | SchoolContext (ContosoUniversity.DAL) öğesini seçin. |
Denetleyici adı | CourseController girin. Yine, bir s ile CoursesController değil. Kurs (ContosoUniversity.Models) öğesini seçtiğinizde Denetleyici adı değeri otomatik olarak doldurulur. Değeri değiştirmeniz gerekir. |
Diğer varsayılan değerleri bırakın ve denetleyiciyi ekleyin.
Controllers\CourseController.cs dosyasını açın ve yöntemine Index
bakın:
public ActionResult Index()
{
var courses = db.Courses.Include(c => c.Department);
return View(courses.ToList());
}
Otomatik yapı iskelesi, yöntemini kullanarak gezinti özelliği için Department
istekli yükleme belirtti Include
.
Views\Course\Index.cshtml dosyasını açın ve şablon kodunu aşağıdaki kodla değiştirin. Değişiklikler vurgulanır:
@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>
yapı iskelesi oluşturulan 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 yapı iskelesi oluşturmaz çünkü normalde son kullanıcılar için anlamsızdır. Ancak, bu durumda birincil anahtar anlamlıdır ve bunu göstermek istersiniz. - Department sütununu sağ tarafa taşımış ve başlığını değiştirmiştir. Yapı iskelesi varlığın
Name
Department
özelliğini doğru bir şekilde görüntülemeyi seçti, ancak burada Kurs sayfasında sütun başlığı Ad yerine Departman olmalıdır.
Department sütununda, iskelesi oluşturulan kodun gezinti özelliğine Name
yüklenen varlığın özelliğini Department
görüntülediğine Department
dikkat edin:
<td>
@Html.DisplayFor(modelItem => item.Department.Name)
</td>
Bölüm adlarını içeren listeyi görmek için sayfayı çalıştırın (Contoso Üniversitesi giriş sayfasındaki 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 listesi varlıkla
OfficeAssignment
ilgili verileri görüntüler.Instructor
veOfficeAssignment
varlıkları bire sıfıra veya bir ilişkisindedir. Varlıklar içinOfficeAssignment
istekli yükleme 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ğitmenlerin 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
istekli yükleme kullanacaksınız. Bu durumda, yalnızca seçilen eğitmen için kurslara ihtiyacınız olduğundan tembel yükleme daha verimli olabilir. Ancak bu örnekte, gezinti özelliklerinde kendileri olan varlıklardaki gezinti özellikleri için istekli 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 ilgiliStudent
varlıklar içinEnrollment
açık yükleme ekleyeceksiniz. (Gecikmeli yükleme etkinleştirildiğinden açık yükleme gerekli değildir, ancak bu açıkça yüklemenin nasıl yapılacağını gösterir.)
Eğitmen Dizin Görünümü için Görünüm Modeli Oluşturma
Eğitmenler sayfasında üç farklı tablo gösterilir. Bu nedenle, her biri tablolardan birine ait verileri tutan üç özellik içeren bir görünüm modeli oluşturacaksınız.
ViewModels klasöründe InstructorIndexData.cs dosyasını oluşturun ve mevcut kodu aşağıdaki kodla değiştirin:
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; }
}
}
Eğitmen Denetleyicisi ve Görünümleri Oluşturma
EF okuma/yazma eylemiyle bir InstructorController
(InstructorsController değil) denetleyicisi oluşturun:
Ayar | Değer |
---|---|
Model sınıfı | Eğitmen (ContosoUniversity.Models) öğesini seçin. |
Veri bağlamı sınıfı | SchoolContext (ContosoUniversity.DAL) öğesini seçin. |
Denetleyici adı | InstructorController yazın. Yine, bir s ile InstructorsController değil. Kurs (ContosoUniversity.Models) öğesini seçtiğinizde Denetleyici adı değeri otomatik olarak dolduruldu. Değeri değiştirmeniz gerekir. |
Diğer varsayılan değerleri bırakın ve denetleyiciyi ekleyin.
Controllers\InstructorController.cs dosyasını açın ve ad alanı için ViewModels
bir using
deyim ekleyin:
using ContosoUniversity.ViewModels;
yöntemindeki Index
yapı iskelesi oluşturulmuş kod, yalnızca gezinti özelliği için OfficeAssignment
istekli yüklemeyi belirtir:
public ActionResult Index()
{
var instructors = db.Instructors.Include(i => i.OfficeAssignment);
return View(instructors.ToList());
}
Index
ek ilgili verileri yüklemek ve görünüm modeline yerleştirmek için yöntemini aşağıdaki kodla değiştirin:
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);
}
yöntemi, seçilen eğitmenin ve seçilen kursun kimlik değerlerini sağlayan isteğe bağlı yol verilerini (id
) ve sorgu dizesi parametresini (courseID
) kabul eder ve tüm gerekli verileri görünüme geçirir. Parametreler sayfadaki Köprü seç seçeneği tarafından sağlanır.
Kod, görünüm modelinin bir örneğini oluşturup eğitmen listesine ekleyerek başlar. Kod, ve Instructor.Courses
gezinti özelliği için Instructor.OfficeAssignment
istekli yüklemeyi belirtir.
var viewModel = new InstructorIndexData();
viewModel.Instructors = db.Instructors
.Include(i => i.OfficeAssignment)
.Include(i => i.Courses.Select(c => c.Department))
.OrderBy(i => i.LastName);
İkinci Include
yöntem Courses'ı yükler ve yüklenen her Kurs için gezinti özelliği için Course.Department
istekli yükleme yapar.
.Include(i => i.Courses.Select(c => c.Department))
Daha önce belirtildiği gibi, istekli yükleme gerekli değildir, ancak performansı artırmak için yapılır. Görünüm her zaman varlığı gerektirdiğinden OfficeAssignment
, aynı sorguda bunu getirmek daha verimlidir. Course
varlıklar, web sayfasında bir eğitmen seçildiğinde gereklidir, bu nedenle istekli yükleme, yalnızca sayfa seçili bir kursta değil de daha sık görüntülendiğinde gecikmeli yüklemeden daha iyidir.
Eğitmen kimliği seçilmişse, seçilen eğitmen görünüm modelindeki eğitmenler listesinden alınır. Ardından görünüm modelinin Courses
özelliği, eğitmenin Course
Courses
gezinti özelliğindeki varlıklarla birlikte yüklenir.
if (id != null)
{
ViewBag.InstructorID = id.Value;
viewModel.Courses = viewModel.Instructors.Where(i => i.ID == id.Value).Single().Courses;
}
Where
yöntemi bir koleksiyon döndürür, ancak bu durumda bu yönteme geçirilen ölçütler yalnızca tek Instructor
bir varlığın döndürülmesine neden olur. yöntemi, Single
koleksiyonu tek Instructor
bir varlığa dönüştürür ve bu sayede bu varlığın Courses
özelliğine erişmenizi sağlar.
Koleksiyonun yalnızca bir öğeye sahip olacağını bildiğinizde bir koleksiyonda Single yöntemini kullanırsınız. yöntemi, Single
geçirilen koleksiyon boşsa veya birden fazla öğe varsa bir özel durum oluşturur. Alternatif olarak, koleksiyon boşsa varsayılan bir değer (null
bu örnekte) döndüren SingleOrDefault kullanılabilir. Ancak, bu durumda bu durum yine de bir özel durumla sonuçlanır (başvuruda null
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ızdaSingle
, yöntemi ayrı olarak çağırmak Where
yerine koşulu da Where
geçirebilirsiniz:
.Single(i => i.ID == id.Value)
Onun yerine:
.Where(I => i.ID == id.Value).Single()
Daha sonra, 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 Enrollment
Enrollments
gezinti özelliğindeki varlıklarla birlikte yüklenir.
if (courseID != null)
{
ViewBag.CourseID = courseID.Value;
viewModel.Enrollments = viewModel.Courses.Where(
x => x.CourseID == courseID).Single().Enrollments;
}
Eğitmen Dizin Görünümünü Değiştirme
Views\Instructor\Index.cshtml içinde şablon kodunu aşağıdaki kodla değiştirin. Değişiklikler vurgulanır:
@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>
Mevcut kodda aşağıdaki değişiklikleri yaptınız:
Model sınıfı olarak
InstructorIndexData
değiştirildi.Dizin olan sayfa başlığı Eğitmenler olarak değiştirildi.
Yalnızca null değilse
item.OfficeAssignment
görüntülenenitem.OfficeAssignment.Location
bir Office sütunu eklendi. (Bu bire sıfıra veya bir ilişkisi olduğundan, ilgiliOfficeAssignment
bir varlık olmayabilir.)<td> @if (item.OfficeAssignment != null) { @item.OfficeAssignment.Location } </td>
Seçili eğitmenin
tr
öğesine dinamik olarak eklenecek kod eklendiclass="success"
. Bu, Bootstrap sınıfını kullanarak seçili satır için bir arka plan rengi ayarlar.string selectedRow = ""; if (item.InstructorID == ViewBag.InstructorID) { selectedRow = "success"; } <tr class="@selectedRow" valign="top">
Her satırdaki diğer bağlantılardan hemen önce Seç etiketli yeni
ActionLink
bir etiket eklendi ve bu da seçilen eğitmen kimliğinin yönteme gönderilmesineIndex
neden oluyor.
Uygulamayı çalıştırın ve Eğitmenler sekmesini seçin. Sayfa, ilişkili varlık olmadığında OfficeAssignment
ilgili OfficeAssignment
varlıkların ve boş bir tablo hücresinin özelliğini görüntülerLocation
.
Views\Instructor\Index.cshtml dosyasında, kapanış table
öğesinden sonra (dosyanın sonuna) aşağıdaki kodu ekleyin. Bu kod, bir 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 == 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>
}
Bu kod, kurs listesini Courses
görüntülemek için görünüm modelinin özelliğini okur. Ayrıca, seçili kursun kimliğini eylem yöntemine Index
gönderen bir Select
köprü sağlar.
Sayfayı çalıştırın ve bir eğitmen seçin. Artık seçili eğitmene atanan dersleri gösteren 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, bir kurs seçildiğinde bir kursa kaydolan öğ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ı çalıştırın 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 Ekleme
InstructorController.cs dosyasını açın ve yöntemin Index
seçilen kursun kayıt listesini nasıl aldığına bakın:
if (courseID != null)
{
ViewBag.CourseID = courseID.Value;
viewModel.Enrollments = viewModel.Courses.Where(
x => x.CourseID == courseID).Single().Enrollments;
}
Eğitmen listesini aldığınızda gezinti özelliği ve her kursun Courses
özelliği için Department
istekli yükleme belirttiniz. Ardından koleksiyonu görünüm modeline Courses
yerleştirirsiniz ve şimdi bu koleksiyondaki Enrollments
bir varlıktan gezinti özelliğine erişiyor olursunuz. Gezinti özelliği için hevesle yüklemeyi belirtmediğiniz için Course.Enrollments
, bu özellikteki veriler gecikmeli yüklemenin bir sonucu olarak sayfada görüntülenir.
Kodu başka bir şekilde değiştirmeden gecikmeli yüklemeyi devre dışı bırakırsanız, kursun Enrollments
gerçekte kaç kaydı olduğuna bakılmaksızın özellik null olur. Bu durumda, özelliği yüklemek Enrollments
için istekli yükleme veya açık yükleme belirtmeniz gerekir. İstekli yüklemeyi nasıl yapacağınızı zaten gördünüz. Açık yükleme örneğini görmek için yöntemini özelliğini açıkça yükleyen Enrollments
aşağıdaki kodla değiştirinIndex
. Değiştirilen kod vurgulanır.
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);
}
Seçilen Course
varlığı aldıktan sonra yeni kod, bu kursun Enrollments
gezinti özelliğini açıkça yükler:
db.Entry(selectedCourse).Collection(x => x.Enrollments).Load();
Ardından her Enrollment
varlığın ilgili Student
varlığını açıkça yükler:
db.Entry(enrollment).Reference(x => x.Student).Load();
Bir koleksiyon özelliğini yüklemek için yöntemini kullandığınıza Collection
, ancak tek bir varlığı barındıran bir özellik için yöntemini kullandığınıza Reference
dikkat edin.
Eğitmen Dizini sayfasını şimdi çalıştırdığınızda, verilerin nasıl alındığını değiştirmiş olmanıza rağmen sayfada görüntülenenler arasında bir fark görmezsiniz.
Kodu alma
Ek kaynaklar
Diğer Entity Framework kaynaklarına bağlantılar ASP.NET Veri Erişimi - Önerilen Kaynaklar bölümünde bulunabilir.
Sonraki adımlar
Bu öğreticide şunları yaptınız:
- İlgili verileri yüklemeyi öğrendin
- Kurslar sayfası oluşturuldu
- Eğitmenler sayfası oluşturuldu
İlgili verileri nasıl güncelleştireceğinizi öğrenmek için sonraki makaleye ilerleyin.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin