ASP.NET MVC Uygulamasında Entity Framework ile İlgili Verileri Okuma (5/10)
tarafından Tom Dykstra
Contoso University örnek web uygulaması, Entity Framework 5 Code First ve Visual Studio 2012 kullanarak ASP.NET MVC 4 uygulamalarının nasıl oluşturulacağını gösterir. Öğretici serisi hakkında bilgi için serideki ilk öğreticiye bakın.
Not
Çözemediğiniz bir sorunla karşılaşırsanız tamamlanmış bölümü indirin ve sorununuzu yeniden oluşturmayı deneyin. Kodunuzu tamamlanmış kodla karşılaştırarak genellikle sorunun çözümünü bulabilirsiniz. Bazı yaygın hatalar ve bunların nasıl çözüldüğü için bkz . Hatalar ve Geçici Çözümler.
Önceki öğreticide School veri modelini tamamladınız. Bu öğreticide, Entity Framework'ün gezinti özelliklerine yüklediğini ilgili verileri okuyacak ve görüntüleyeceksiniz.
Aşağıdaki çizimlerde, çalışacağınız sayfalar gösterilmektedir.
İlgili Verilerin Gecikmeli, Istekli ve Açık Yüklenmesi
Entity Framework'ün ilgili verileri bir varlığın gezinti özelliklerine yüklemesinin çeşitli yolları vardır:
Tembel yükleme. Varlık ilk kez 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. Bu sorgulardan biri varlığın kendisi için, diğeri de varlıkla ilgili verilerin her alınması gerektiğinde alınır.
Hevesle yükleniyor. 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 hevesle
Include
yüklemeyi 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 durum yöneticisi girdisini alıp koleksiyonlar için yöntemini veya tek bir varlığı barındıran özelliklerin
Reference.Load
yöntemini çağırarakCollection.Load
ilgili verileri el ile yüklersiniz. (Aşağıdaki örnekte, Yönetici gezinti özelliğini yüklemek istiyorsanız değerini ileReference(x => x.Administrator)
değiştirirsinizCollection(x => x.Courses)
.)
Özellik değerlerini hemen almadıkları için gecikmeli yükleme ve açık yükleme de ertelenmiş yükleme olarak bilinir.
Genel olarak, 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 en iyi performansı sunar. Örneğin, yukarıdaki örneklerde her bölümün on ilgili kursu olduğunu varsayalım. İstekli yükleme örneği 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 sorgu hem de veritabanına on bir gidiş dönüşle sonuçlanır. Veritabanına fazladan gidiş dönüşler, gecikme süresi yüksek olduğunda performans açısından özellikle zarara neden olabilir.
Öte yandan bazı senaryolarda gecikmeli yükleme daha verimlidir. İstekli yükleme, SQL Server verimli bir şekilde işleyememesine neden olan çok karmaşık bir birleştirmenin oluşturulmasına neden olabilir. Öte yandan, bir varlığın gezinti özelliklerine yalnızca işlemekte olduğunuz bir varlık kümesinin alt kümesi için erişmeniz gerekiyorsa, hevesle yükleme size gerekenden 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.
Genellikle açık yüklemeyi yalnızca gecikmeli yüklemeyi kapattığınızda kullanırsınız. Gecikmeli yüklemeyi kapatmanız gereken senaryolardan biri serileştirme sırasındadır. Gecikmeli yükleme ve serileştirme iyi karışmaz ve dikkatli değilseniz, yavaş yükleme etkinleştirildiğinde hedeflediğ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. Seri hale getirme işlemi daha sonra gecikmeli yüklenen varlıkların her özelliğine erişerek daha da gecikmeli yükleme ve serileştirmeye neden olabilir. Bu run-away zincir reaksiyonu önlemek için, bir varlığı seri hale getirmeden önce gecikmeli yüklemeyi kapatın.
Veritabanı bağlam sınıfı varsayılan olarak gecikmeli yükleme gerçekleştirir. Gecikmeli yüklemeyi devre dışı bırakmanın iki yolu vardır:
Belirli gezinti özellikleri için, özelliğini bildirirken anahtar sözcüğünü atla
virtual
.Tüm gezinti özellikleri için olarak
false
ayarlayınLazyLoadingEnabled
. Örneğin, bağlam sınıfınızın oluşturucusunda aşağıdaki kodu koyabilirsiniz:this.Configuration.LazyLoadingEnabled = false;
Gecikmeli 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ıyla karşılaşabilir. Veritabanı sorgularının profilini gerçekçi bir test yüküyle oluşturmak, gecikmeli yüklemenin uygun olup olmadığını belirlemenize yardımcı olur. Daha fazla bilgi için bkz. Entity Framework Stratejilerini Çözme: İlgili Verileri Yükleme ve Ağ Gecikme süresini azaltmak için Entity Framework'ün SQL Azure kullanma.
Bölüm Adını Görüntüleyen Kurs Dizini 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 gösterildiği gibi denetleyici için daha önce yaptığınız seçenekleri kullanarak varlık türü için Course
Student
adlı CourseController
bir denetleyici oluşturun (görüntünün aksine bağlam sınıfınız Models ad alanında değil DAL ad alanındadır):
Controllers\CourseController.cs dosyasını açın ve yöntemine Index
bakın:
public ViewResult Index()
{
var courses = db.Courses.Include(c => c.Department);
return View(courses.ToList());
}
Otomatik yapı iskelesi, yöntemini kullanarak Include
gezinti özelliği için Department
istekli yükleme belirtti.
Views\Course\Index.cshtml dosyasını açın ve mevcut kodu 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>
<tr>
<th></th>
<th>Number</th>
<th>Title</th>
<th>Credits</th>
<th>Department</th>
</tr>
@foreach (var item in Model) {
<tr>
<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>
<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>
</tr>
}
</table>
İskelesi oluşturulan kodda aşağıdaki değişiklikleri yaptınız:
- Dizin başlığı, Kurslar olarak değiştirildi.
- Satır bağlantılarını sola taşıdı.
- Sayı başlığının altına özellik değerini gösteren
CourseID
bir sütun eklendi. (Varsayılan olarak, birincil anahtarlar son kullanıcılar için anlamsız olduğundan iskelesi kurulmamaktadır. Ancak, bu durumda birincil anahtar anlamlıdır ve bunu göstermek istersiniz.) - DepartmentID (varlığın yabancı anahtarının
Department
adı) olan son sütun başlığı Department olarak değiştirildi.
Son sütunda, iskelesi oluşturulan kodun Name
gezinti özelliğine 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).
Kursları ve Kayıtları Gösteren Eğitmen Dizini Sayfası Oluşturma
Bu bölümde eğitmen dizini sayfasını görüntülemek için Instructor
bir denetleyici oluşturacak ve varlığı görüntüleyeceksiniz:
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ç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ğitmen Dizini 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; }
}
}
Seçili Satırlar için Stil Ekleme
Seçili satırları işaretlemek için farklı bir arka plan rengi gerekir. Bu kullanıcı arabirimine stil sağlamak için, aşağıda gösterildiği gibi Content\Site.css'deki bölümüne /* info and errors */
aşağıdaki vurgulanmış kodu ekleyin:
/* info and errors */
.selectedrow
{
background-color: #a4d4e6;
}
.message-info {
border: 1px solid;
clear: both;
padding: 10px 20px;
}
Eğitmen Denetleyicisi ve Görünümleri Oluşturma
Aşağıdaki çizimde gösterildiği gibi bir InstructorController
denetleyici oluşturun:
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 ViewResult 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.InstructorID == 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.
İpucu
Veri yönlendirme
Yönlendirme verileri, model bağlayıcısının yönlendirme tablosunda belirtilen bir URL kesiminde bulduğu verilerdir. Örneğin, varsayılan yol , action
ve id
kesimlerini belirtircontroller
:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Aşağıdaki URL'de varsayılan yol, action
Index
ile ve 1 ile id
eşlenir Instructor
controller
; bunlar yol veri değerleridir.
http://localhost:1230/Instructor/Index/1?courseID=2021
"?courseID=2021" bir sorgu dizesi değeridir. Model bağlayıcısı, sorgu dizesi değeri olarak geçirirseniz id
de çalışır:
http://localhost:1230/Instructor/Index?id=1&CourseID=2021
URL'ler Razor görünümündeki deyimler tarafından ActionLink
oluşturulur. Aşağıdaki kodda id
parametresi varsayılan yol ile eşleşir, bu nedenle id
yol verilerine eklenir.
@Html.ActionLink("Select", "Index", new { id = item.PersonID })
Aşağıdaki kodda, courseID
varsayılan yoldaki bir parametreyle eşleşmediğinden sorgu dizesi olarak eklenir.
@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
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.InstructorID == 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.InstructorID == id.Value)
Onun yerine:
.Where(I => i.InstructorID == 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 Dizini Görünümünü Değiştirme
Views\Instructor\Index.cshtml içinde var olan kodu 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>
<tr>
<th></th>
<th>Last Name</th>
<th>First Name</th>
<th>Hire Date</th>
<th>Office</th>
</tr>
@foreach (var item in Model.Instructors)
{
string selectedRow = "";
if (item.InstructorID == ViewBag.InstructorID)
{
selectedRow = "selectedrow";
}
<tr class="@selectedRow" valign="top">
<td>
@Html.ActionLink("Select", "Index", new { id = item.InstructorID }) |
@Html.ActionLink("Edit", "Edit", new { id = item.InstructorID }) |
@Html.ActionLink("Details", "Details", new { id = item.InstructorID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.InstructorID })
</td>
<td>
@item.LastName
</td>
<td>
@item.FirstMidName
</td>
<td>
@Html.DisplayFor(modelItem => item.HireDate)
</td>
<td>
@if (item.OfficeAssignment != null)
{
@item.OfficeAssignment.Location
}
</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.
Satır bağlantısı sütunları sola taşındı.
FullName sütunu kaldırıldı.
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="selectedrow"
. Bu, daha önce oluşturduğunuz CSS sınıfını kullanarak seçili satır için bir arka plan rengi ayarlar. (Özniteliği,valign
tabloya çok satırlı bir sütun eklediğinizde aşağıdaki öğreticide yararlı olacaktır.)string selectedRow = ""; if (item.InstructorID == ViewBag.InstructorID) { selectedRow = "selectedrow"; } <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 sonunda), aşağıdaki vurgulanmış kodu ekleyin. Bu, bir eğitmen seçildiğinde eğitmenle ilgili derslerin listesini görüntüler.
<td>
@if (item.OfficeAssignment != null)
{
@item.OfficeAssignment.Location
}
</td>
</tr>
}
</table>
@if (Model.Courses != null)
{
<h3>Courses Taught by Selected Instructor</h3>
<table>
<tr>
<th></th>
<th>ID</th>
<th>Title</th>
<th>Department</th>
</tr>
@foreach (var item in Model.Courses)
{
string selectedRow = "";
if (item.CourseID == ViewBag.CourseID)
{
selectedRow = "selectedrow";
}
<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.
Not
.css dosyası tarayıcılar tarafından önbelleğe alınır. Uygulamayı çalıştırdığınızda değişiklikleri görmüyorsanız, sabit yenileme yapın ( Yenile düğmesine tıklarken CTRL tuşunu basılı tutun veya CTRL+F5 tuşlarına basın).
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>
<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.InstructorID == id.Value).Single().Courses;
}
if (courseID != null)
{
ViewBag.CourseID = courseID.Value;
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ırabilirsiniz ve verilerin nasıl alındığını değiştirmiş olmanıza rağmen sayfada görüntülenenler arasında bir fark görmezsiniz.
Özet
Artık ilgili verileri gezinti özelliklerine yüklemek için üç yolu da (gecikmeli, istekli ve açık) kullandınız. Sonraki öğreticide ilgili verileri nasıl güncelleştireceğinizi öğreneceksiniz.
Diğer Entity Framework kaynaklarına bağlantılar ASP.NET Veri Erişimi İçerik Eşlemesi'nde bulunabilir.
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