Čtení souvisejících dat pomocí Entity Frameworku v aplikaci ASP.NET MVC (5 z 10)
Ukázková webová aplikace Contoso University ukazuje, jak vytvářet aplikace ASP.NET MVC 4 pomocí entity Framework 5 Code First a sady Visual Studio 2012. Informace o sérii kurzů najdete v prvním kurzu v této sérii.
Poznámka
Pokud narazíte na problém, který nemůžete vyřešit, stáhněte si dokončenou kapitolu a zkuste problém reprodukovat. Obecně můžete najít řešení problému porovnáním kódu s dokončeným kódem. Informace o některých běžných chybách a jejich řešení najdete v tématu Chyby a alternativní řešení.
V předchozím kurzu jste dokončili školní datový model. V tomto kurzu budete číst a zobrazovat související data – to znamená data, která Entity Framework načte do navigačních vlastností.
Následující ilustrace znázorňují stránky, se kterými budete pracovat.
Opožděné, nedočkavé a explicitní načítání souvisejících dat
Existuje několik způsobů, jak může Entity Framework načíst související data do navigačních vlastností entity:
Opožděné načítání. Při prvním čtení entity se související data nenačtou. Při prvním pokusu o přístup k navigační vlastnosti se však automaticky načtou data potřebná pro tuto navigační vlastnost. Výsledkem je několik dotazů odeslaných do databáze – jeden pro samotnou entitu a druhý pokaždé, když se musí načíst související data entity.
Dychtivé načítání. Když se entita načte, načtou se spolu s ní i související data. Výsledkem je obvykle jeden dotaz spojení, který načte všechna potřebná data. K určení dychtivého načítání použijete metodu
Include
.Explicitní načítání To se podobá opožděné načítání, s výjimkou toho, že explicitně načtete související data v kódu; nedojde k tomu automaticky při přístupu k vlastnosti navigace. Související data načtete ručně tak, že získáte položku správce stavu objektu pro entitu a zavoláte metodu
Collection.Load
pro kolekce nebo metoduReference.Load
pro vlastnosti, které obsahují jednu entitu. (Pokud byste v následujícím příkladu chtěli načíst navigační vlastnost Správce, nahradiliCollection(x => x.Courses)
Reference(x => x.Administrator)
byste za .)
Vzhledem k tomu, že nenačítají hodnoty vlastností okamžitě, líné načítání i explicitní načítání se také označuje jako odložené načítání.
Obecně platí, že pokud víte, že potřebujete související data pro každou načtenou entitu, nabízí dychtivé načítání nejlepší výkon, protože jeden dotaz odeslaný do databáze je obvykle efektivnější než samostatné dotazy pro každou načtenou entitu. Ve výše uvedených příkladech předpokládejme, že každé oddělení má deset souvisejících kurzů. Výsledkem příkladu s dychtivým načítáním by byl jen jeden dotaz (join) a jedna cesta k databázi. Opožděné načítání a explicitní načítání příkladů by vedlo k jedenácti dotazům a jedenácti odezvám do databáze. Dodatečné doby odezvy do databáze jsou zvláště škodlivé pro výkon při vysoké latenci.
Na druhou stranu v některých scénářích je opožděné načítání efektivnější. Dychtivé načítání může způsobit vygenerování velmi složitého spojení, které SQL Server nedokáže efektivně zpracovat. Nebo pokud potřebujete získat přístup k navigačním vlastnostem entity pouze pro podmnožinu zpracovávaných entit, může opožděné načítání fungovat lépe, protože by se načetlo více dat, než potřebujete. Pokud je výkon kritický, je nejlepší otestovat ho oběma způsoby, abyste mohli zvolit tu nejlepší volbu.
Obvykle byste použili explicitní načítání, pouze pokud jste vypnuli opožděné načítání. Jedním ze scénářů, kdy byste měli vypnout opožděné načítání, je během serializace. Opožděné načítání a serializace se dobře nekombinují, a pokud nejste opatrní, můžete nakonec dotazovat výrazně více dat, než jste zamýšleli, když je povolené opožděné načítání. Serializace obecně funguje tak, že přístup k každé vlastnosti instance typu. Přístup k vlastnostem aktivuje opožděné načítání a tyto líně načtené entity jsou serializovány. Proces serializace pak přistupuje ke každé vlastnosti opožděně načtených entit, což může způsobit ještě více opožděné načítání a serializace. Chcete-li zabránit této utíknutí řetězové reakce, vypněte opožděné načítání před serializací entity.
Třída kontextu databáze provádí ve výchozím nastavení opožděné načítání. Existují dva způsoby, jak zakázat opožděné načítání:
Pro konkrétní navigační vlastnosti vyněžte
virtual
klíčové slovo při deklaraci vlastnosti.Pro všechny vlastnosti navigace nastavte
LazyLoadingEnabled
nafalse
. Do konstruktoru třídy kontextu můžete například vložit následující kód:this.Configuration.LazyLoadingEnabled = false;
Opožděné načítání může maskovat kód, který způsobuje problémy s výkonem. Například kód, který neurčuje dychtivé nebo explicitní načítání, ale zpracovává velké množství entit a v každé iteraci používá několik navigačních vlastností, může být velmi neefektivní (z důvodu mnoha cest do databáze). Aplikace, která dobře funguje při vývoji pomocí místního SQL Serveru, může mít při přesunu do Azure SQL Database problémy s výkonem z důvodu zvýšené latence a opožděného načítání. Profilace databázových dotazů s realistickým testovacím zatížením vám pomůže určit, jestli je opožděné načítání vhodné. Další informace najdete v tématech Demystifikace strategií Entity Framework: Načítání souvisejících dat a Použití Entity Framework ke snížení latence sítě na SQL Azure.
Vytvoření indexové stránky kurzů, která zobrazuje název oddělení
Entita Course
obsahuje navigační vlastnost, která obsahuje entitu Department
oddělení, ke kterému je kurz přiřazený. Pokud chcete zobrazit název přiřazeného oddělení v seznamu kurzů, musíte vlastnost získat Name
z Department
entity, která je v Course.Department
navigační vlastnosti.
Vytvořte kontroler s názvem CourseController
pro Course
typ entity pomocí stejných možností, které jste předtím použili pro Student
kontroler, jak je znázorněno na následujícím obrázku (s výjimkou obrázku je vaše třída kontextu v oboru názvů DAL, ne v oboru názvů Models):
Otevřete soubor Controllers\CourseController.cs a podívejte se na metodu Index
:
public ViewResult Index()
{
var courses = db.Courses.Include(c => c.Department);
return View(courses.ToList());
}
Automatické generování uživatelského rozhraní určilo nedočkavé načítání pro Department
vlastnost navigace pomocí Include
metody .
Otevřete Views\Course\Index.cshtml a nahraďte existující kód následujícím kódem. Změny jsou zvýrazněné:
@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>
Provedli jste následující změny v vygenerovaného kódu:
- Změnili jsme nadpis z Index na Courses (Kurzy).
- Odkazy řádků se přesunuly doleva.
- Pod nadpisEm Číslo byl přidán sloupec, který zobrazuje
CourseID
hodnotu vlastnosti. (Ve výchozím nastavení se primární klíče nevygenerují, protože obvykle nejsou pro koncové uživatele smysluplné. V tomto případě je ale primární klíč smysluplný a chcete ho zobrazit.) - Změnili jsme záhlaví posledního sloupce z DepartmentID (název cizího klíče entity
Department
) na Oddělení.
Všimněte si, že pro poslední sloupec zobrazí vygenerovaný kód Name
vlastnost Department
entity, která je načtená do Department
vlastnosti navigace:
<td>
@Html.DisplayFor(modelItem => item.Department.Name)
</td>
Spusťte stránku (na domovské stránce Contoso University vyberte kartu Kurzy ) a zobrazte seznam s názvy oddělení.
Vytvoření indexové stránky instruktorů, která zobrazuje kurzy a zápisy
V této části vytvoříte kontroler a zobrazení entity, Instructor
abyste zobrazili stránku Index instruktorů:
Tato stránka čte a zobrazuje související data následujícími způsoby:
- Seznam instruktorů zobrazuje související data z
OfficeAssignment
entity. EntityInstructor
aOfficeAssignment
jsou v relaci 1:0 nebo 1. Pro entity použijete dychtivéOfficeAssignment
načítání. Jak jsme si vysvětlili dříve, načítání dychtivých dat je obvykle efektivnější, když potřebujete související data pro všechny načtené řádky primární tabulky. V tomto případě chcete zobrazit přiřazení kanceláře pro všechny zobrazené instruktory. - Když uživatel vybere instruktora, zobrazí se související
Course
entity. EntityInstructor
aCourse
jsou v relaci M:N. Pro entity a souvisejícíDepartment
entity použijete dychtivéCourse
načítání. V takovém případě může být opožděné načítání efektivnější, protože kurzy potřebujete jenom pro vybraného instruktora. Tento příklad však ukazuje, jak použít dychtivé načítání pro navigační vlastnosti v rámci entit, které jsou samy v navigačních vlastnostech. - Když uživatel vybere kurz, zobrazí se
Enrollments
související data ze sady entit. EntityCourse
aEnrollment
jsou v relaci 1:N. Přidáte explicitní načítání entitEnrollment
a souvisejícíchStudent
entit. (Explicitní načítání není nutné, protože je povolené opožděné načítání, ale to ukazuje, jak provést explicitní načítání.)
Vytvoření modelu zobrazení pro indexové zobrazení instruktora
Na stránce Index instruktora se zobrazují tři různé tabulky. Proto vytvoříte model zobrazení, který obsahuje tři vlastnosti, z nichž každá obsahuje data jedné z tabulek.
Ve složce ViewModels vytvořte soubor InstructorIndexData.cs a nahraďte existující kód následujícím kódem:
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; }
}
}
Přidání stylu pro vybrané řádky
K označení vybraných řádků potřebujete jinou barvu pozadí. Pokud chcete poskytnout styl pro toto uživatelské rozhraní, přidejte do oddílu /* info and errors */
Content\Site.css následující zvýrazněný kód, jak je znázorněno níže:
/* info and errors */
.selectedrow
{
background-color: #a4d4e6;
}
.message-info {
border: 1px solid;
clear: both;
padding: 10px 20px;
}
Vytvoření kontroleru instruktora a zobrazení
Vytvořte InstructorController
kontroler, jak je znázorněno na následujícím obrázku:
Otevřete soubor Controllers\InstructorController.cs a přidejte using
příkaz pro ViewModels
obor názvů:
using ContosoUniversity.ViewModels;
Vygenerovaný kód v Index
metodě určuje nedočkavé načítání pouze pro OfficeAssignment
vlastnost navigace:
public ViewResult Index()
{
var instructors = db.Instructors.Include(i => i.OfficeAssignment);
return View(instructors.ToList());
}
Nahraďte metodu Index
následujícím kódem, který načte další související data a vloží je do modelu zobrazení:
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);
}
Metoda přijímá volitelná data trasy (id
) a parametr řetězce dotazu (courseID
), které poskytují hodnoty ID vybraného instruktora a vybraného kurzu, a předá všechna požadovaná data do zobrazení. Parametry jsou poskytovány výběrem hypertextových odkazů na stránce.
Tip
Směrování dat
Směrovací data jsou data, která modelový pořadač našel v segmentu adresy URL zadaném ve směrovací tabulce. Výchozí trasa například určuje controller
, action
a id
segmenty:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Na následující adrese URL se výchozí trasa mapuje Instructor
jako controller
, Index
jako action
a 1 jako id
. Jedná se o datové hodnoty trasy.
http://localhost:1230/Instructor/Index/1?courseID=2021
"?courseID=2021" je hodnota řetězce dotazu. Pořadač modelu bude fungovat také v případě, že jako hodnotu řetězce dotazu předáte id
hodnotu:
http://localhost:1230/Instructor/Index?id=1&CourseID=2021
Adresy URL se vytvářejí příkazy ActionLink
v zobrazení Razor. V následujícím kódu id
se parametr shoduje s výchozí trasou, takže id
se přidá do dat trasy.
@Html.ActionLink("Select", "Index", new { id = item.PersonID })
V následujícím kódu courseID
neodpovídá parametru ve výchozí trase, takže se přidá jako řetězec dotazu.
@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
Kód začíná vytvořením instance modelu zobrazení a zařazením seznamu instruktorů. Kód určuje nedočkavé načítání vlastnosti Instructor.OfficeAssignment
a Instructor.Courses
navigation.
var viewModel = new InstructorIndexData();
viewModel.Instructors = db.Instructors
.Include(i => i.OfficeAssignment)
.Include(i => i.Courses.Select(c => c.Department))
.OrderBy(i => i.LastName);
Druhá Include
metoda načte kurzy a pro každý kurz, který je načten, se načte dychtivě pro Course.Department
vlastnost navigace.
.Include(i => i.Courses.Select(c => c.Department))
Jak už bylo zmíněno dříve, nedočkavé načítání se nevyžaduje, ale provádí se za účelem zvýšení výkonu. Vzhledem k tomu, že zobrazení vždy vyžaduje entitu OfficeAssignment
, je efektivnější ji načíst ve stejném dotazu. Course
Entity jsou vyžadovány, když je na webové stránce vybrán instruktor, takže dychtivé načítání je lepší než opožděné načítání pouze v případě, že se stránka zobrazuje častěji s vybraným kurzem než bez.
Pokud bylo vybráno ID instruktora, vybraný instruktor se načte ze seznamu instruktorů v modelu zobrazení. Vlastnost modelu Courses
zobrazení se pak načte Course
s entitami z navigační vlastnosti daného instruktora Courses
.
if (id != null)
{
ViewBag.InstructorID = id.Value;
viewModel.Courses = viewModel.Instructors.Where(i => i.InstructorID == id.Value).Single().Courses;
}
Metoda Where
vrátí kolekci, ale v tomto případě kritéria předaná této metodě způsobí, že se vrátí pouze jedna Instructor
entita. Metoda Single
převede kolekci na jednu Instructor
entitu, která vám poskytne přístup k vlastnosti této entity Courses
.
Metodu Single použijete u kolekce, pokud víte, že kolekce bude obsahovat pouze jednu položku. Metoda Single
vyvolá výjimku, pokud je kolekce předaná do ní prázdná nebo pokud existuje více než jedna položka. Alternativou je SingleOrDefault, která vrací výchozí hodnotu (null
v tomto případě), pokud je kolekce prázdná. V tomto případě by to však stále vedlo k výjimce (od pokusu Courses
o nalezení vlastnosti u null
odkazu) a zpráva o výjimce by méně jasně označovala příčinu problému. Při volání Single
metody můžete také předat podmínku Where
místo volání Where
metody samostatně:
.Single(i => i.InstructorID == id.Value)
Namísto:
.Where(I => i.InstructorID == id.Value).Single()
Pokud byl dále vybrán kurz, vybraný kurz se načte ze seznamu kurzů v modelu zobrazení. Potom se vlastnost modelu Enrollments
zobrazení načte Enrollment
s entitami z navigační vlastnosti daného kurzu Enrollments
.
if (courseID != null)
{
ViewBag.CourseID = courseID.Value;
viewModel.Enrollments = viewModel.Courses.Where(
x => x.CourseID == courseID).Single().Enrollments;
}
Úprava zobrazení indexu instruktora
V souboru Views\Instructor\Index.cshtml nahraďte existující kód následujícím kódem. Změny jsou zvýrazněné:
@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>
V existujícím kódu jste provedli následující změny:
Změnila se třída modelu na
InstructorIndexData
.Změnil se název stránky z Index na Instruktory.
Přesunutí sloupců s odkazem na řádek doleva
Byl odebrán sloupec FullName .
Přidali jsme sloupec Office , který se zobrazí
item.OfficeAssignment.Location
jenom v případěitem.OfficeAssignment
, že není null. (Vzhledem k tomu, že se jedná o relaci 1:nula nebo 1, nemusí existovat souvisejícíOfficeAssignment
entita.)<td> @if (item.OfficeAssignment != null) { @item.OfficeAssignment.Location } </td>
Byl přidán kód, který bude dynamicky přidávat
class="selectedrow"
dotr
prvku vybraného instruktora. Tím nastavíte barvu pozadí vybraného řádku pomocí třídy CSS, kterou jste vytvořili dříve. (Atributvalign
bude užitečný v následujícím kurzu, když do tabulky přidáte sloupec s více řádky.)string selectedRow = ""; if (item.InstructorID == ViewBag.InstructorID) { selectedRow = "selectedrow"; } <tr class="@selectedRow" valign="top">
Přidání nového
ActionLink
popisku Select bezprostředně před ostatní odkazy v každém řádku, což způsobí, že vybrané ID instruktoraIndex
se odešle do metody.
Spusťte aplikaci a vyberte kartu Instruktoři . Stránka zobrazí Location
vlastnost souvisejících OfficeAssignment
entit a prázdnou buňku tabulky, pokud neexistuje žádná související OfficeAssignment
entita.
V souboru Views\Instructor\Index.cshtml přidejte za uzavírací table
prvek (na konci souboru) následující zvýrazněný kód. Zobrazí se seznam kurzů souvisejících s instruktorem při výběru instruktora.
<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>
}
Tento kód přečte Courses
vlastnost modelu zobrazení pro zobrazení seznamu kurzů. Poskytuje Select
také hypertextový odkaz, který odešle ID vybraného kurzu metodě Index
akce.
Poznámka
Soubory .css se ukládají do mezipaměti prohlížečů. Pokud se změny při spuštění aplikace nezobrazí, proveďte pevnou aktualizaci (podržte stisknutou klávesu CTRL a klikněte na tlačítko Aktualizovat nebo stiskněte kombinaci kláves CTRL+F5).
Spusťte stránku a vyberte instruktora. Teď se zobrazí mřížka, která zobrazuje kurzy přiřazené vybranému instruktorovi a pro každý kurz uvidíte název přiřazeného oddělení.
Za blok kódu, který jste právě přidali, přidejte následující kód. Zobrazí se seznam studentů, kteří jsou do kurzu zapsáni, když je tento kurz vybrán.
@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>
}
Tento kód přečte Enrollments
vlastnost modelu zobrazení, aby se zobrazil seznam studentů zaregistrovaných do kurzu.
Spusťte stránku a vyberte instruktora. Pak vyberte kurz a zobrazte seznam zaregistrovaných studentů a jejich známek.
Přidání explicitního načítání
Otevřete soubor InstructorController.cs a podívejte se, jak Index
metoda získá seznam registrací pro vybraný kurz:
if (courseID != null)
{
ViewBag.CourseID = courseID.Value;
viewModel.Enrollments = viewModel.Courses.Where(
x => x.CourseID == courseID).Single().Enrollments;
}
Když jste získali seznam instruktorů, zadali jste dychtivé načítání pro Courses
vlastnost navigace a vlastnost Department
každého kurzu. Potom vložíte kolekci Courses
do modelu zobrazení a teď přistupujete k Enrollments
vlastnosti navigace z jedné entity v této kolekci. Vzhledem k tomu, že jste pro Course.Enrollments
vlastnost navigace nezadali nedočkavé načítání, zobrazují se data z této vlastnosti na stránce v důsledku opožděného načítání.
Pokud jste zakázali opožděné načítání bez jakékoli jiné změny kódu, Enrollments
vlastnost by byla null bez ohledu na počet registrací, které kurz skutečně měl. V takovém případě byste museli pro načtení Enrollments
vlastnosti zadat buď dychtivé načítání, nebo explicitní načtení. Už jste viděli, jak provádět dychtivé načítání. Pokud chcete vidět příklad explicitního načtení, nahraďte metodu Index
následujícím kódem, který explicitně načte Enrollments
vlastnost. Změněný kód je zvýrazněný.
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);
}
Po získání vybrané Course
entity nový kód explicitně načte navigační vlastnost kurzu Enrollments
:
db.Entry(selectedCourse).Collection(x => x.Enrollments).Load();
Pak explicitně načte související Student
entitu každé Enrollment
entity:
db.Entry(enrollment).Reference(x => x.Student).Load();
Všimněte si, že používáte metodu Collection
k načtení vlastnosti kolekce, ale pro vlastnost, která obsahuje pouze jednu entitu, použijete metodu Reference
. Teď můžete spustit stránku Index instruktora a neuvidíte žádný rozdíl v tom, co se na stránce zobrazuje, i když jste změnili způsob načítání dat.
Souhrn
Teď jste použili všechny tři způsoby (líné, dychtivé a explicitní) k načtení souvisejících dat do navigačních vlastností. V dalším kurzu se dozvíte, jak aktualizovat související data.
Odkazy na další prostředky Entity Framework najdete v mapě obsahu ASP.NET Data Access.