Kurz: Čtení souvisejících dat pomocí EF v aplikaci ASP.NET MVC
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.
Ukázková webová aplikace Contoso University ukazuje, jak vytvářet aplikace ASP.NET MVC 5 pomocí Entity Framework 6 Code First a sady Visual Studio. Informace o sérii kurzů najdete v prvním kurzu v této sérii.
V tomto kurzu jste:
- Zjistěte, jak načíst související data.
- Vytvoření stránky Kurzy
- Vytvoření stránky instruktorů
Požadavky
Zjistěte, jak načíst související data.
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. Třída
DbContext
ve výchozím nastavení umožňuje opožděné načítání.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 metodu Reference.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, nahradili
Collection(x => x.Courses)
Reference(x => x.Administrator)
byste za .) Obvykle byste použili explicitní načítání, pouze pokud jste vypnuli opožděné načítání.
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í.
Otázky výkonu
Pokud víte, že potřebujete související data pro každou načtenou entitu, často nabízí nejlepší výkon dychtivé načítání, 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.
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.
Zakázat opožděné načítání před serializací
Pokud necháte opožděné načítání povoleno během serializace, můžete skončit dotazování výrazně více dat, než jste zamýšleli. 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.
Serializace může být také komplikována proxy třídami, které Entity Framework používá, jak je vysvětleno v kurzu Pokročilé scénáře.
Jedním ze způsobů, jak se vyhnout problémům se serializací, je serializovat objekty pro přenos dat (DTO) místo objektů entit, jak je znázorněno v kurzu Použití webového rozhraní API s Rozhraním Entity Framework .
Pokud nepoužíváte DTO, můžete zakázat opožděné načítání a vyhnout se problémům s proxy serverem zakázáním vytváření proxy serveru.
Tady je několik dalších způsobů, 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 navigační vlastnosti nastavte
LazyLoadingEnabled
nafalse
, vložte do konstruktoru třídy kontextu následující kód:this.Configuration.LazyLoadingEnabled = false;
Vytvoření stránky Kurzy
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
(nikoli CoursesController) pro Course
typ entity pomocí stejných možností pro kontroler MVC 5 se zobrazeními pomocí scaffolderu Entity Framework, který jste pro Student
kontroler udělali dříve:
Nastavení | Hodnota |
---|---|
Třída modelu | Vyberte Course (ContosoUniversity.Models). |
Třída kontextu dat | Vyberte SchoolContext (ContosoUniversity.DAL). |
Název kontroleru | Zadejte CourseController. Opět ne CoursesController se s. Když jste vybrali Course (ContosoUniversity.Models) (Kurz (ContosoUniversity.Models), automaticky se vyplní hodnota Názvu kontroleru . Musíte změnit hodnotu. |
Ostatní výchozí hodnoty ponechte a přidejte kontroler.
Otevřete soubor Controllers\CourseController.cs a podívejte se na metodu Index
:
public ActionResult 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 kód šablony 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 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>
Provedli jste následující změny v vygenerovaného kódu:
- Změnili jsme nadpis z Index na Courses (Kurzy).
- Byl přidán sloupec Číslo , který zobrazuje
CourseID
hodnotu vlastnosti. Ve výchozím nastavení se primární klíče nevygenerují, protože obvykle nemají pro koncové uživatele smysl. V tomto případě je ale primární klíč smysluplný a vy ho chcete zobrazit. - Sloupec Department (Oddělení ) se přesunul na pravou stranu a změnilo se jeho záhlaví. Správce kódu správně zvolil zobrazení
Name
vlastnosti zDepartment
entity, ale tady na stránce Course by záhlaví sloupce mělo být Department (Oddělení ) a ne Name (Název).
Všimněte si, že pro sloupec Department (Oddělení) zobrazuje vygenerovaný kód Name
vlastnost Department
entity, která je načtená do Department
navigační vlastnosti:
<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í stránky instruktorů
V této části vytvoříte kontroler a zobrazení entity, Instructor
abyste zobrazili stránku Instruktori. 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 takovém 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 jejich souvisejícíDepartment
entity použijete dychtivéCourse
načítání. V tomto případě může být opožděné načítání efektivnější, protože kurzy potřebujete pouze 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 o sobě ve vlastnostech navigace. - Když uživatel vybere kurz, zobrazí se související data ze
Enrollments
sady entit. EntityCourse
aEnrollment
jsou v relaci 1:N. Přidáte explicitní načítání proEnrollment
entity a jejich souvisejícíStudent
entity. (Explicitní načítání není nutné, protože je povolené opožděné načítání, ale ukazuje, jak provést explicitní načítání.)
Vytvoření modelu zobrazení pro zobrazení indexového zobrazení instruktora
Na stránce Instruktoři se zobrazují tři různé tabulky. Proto vytvoříte model zobrazení, který obsahuje tři vlastnosti, z nichž každá obsahuje data pro jednu 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; }
}
}
Vytvoření kontroleru a zobrazení instruktora
InstructorController
Vytvořte kontroler (ne InstructorsController) s akcí ef pro čtení/zápis:
Nastavení | Hodnota |
---|---|
Třída modelu | Vyberte Instruktor (ContosoUniversity.Models). |
Třída kontextu dat | Vyberte SchoolContext (ContosoUniversity.DAL). |
Název kontroleru | Zadejte InstructorController. Opět ne InstruktoryController se s. Když jste vybrali Kurz (ContosoUniversity.Models), automaticky se naplnila hodnota Názvu kontroleru . Musíte změnit hodnotu. |
Ponechte ostatní výchozí hodnoty a přidejte kontroler.
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 ActionResult 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.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);
}
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.
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.ID == 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.ID == id.Value)
Namísto:
.Where(I => i.ID == 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 kód šablony 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 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>
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ř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="success"
dotr
prvku vybraného instruktora. Tím nastavíte barvu pozadí vybraného řádku pomocí třídy Bootstrap .string selectedRow = ""; if (item.InstructorID == ViewBag.InstructorID) { selectedRow = "success"; } <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í kód. Tento kód zobrazí seznam kurzů souvisejících s instruktorem při výběru instruktora.
@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>
}
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.
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 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>
}
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.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);
}
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
.
Spusťte teď 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.
Získání kódu
Další materiály
Odkazy na další prostředky Entity Frameworku najdete v tématu ASP.NET Přístup k datům – doporučené zdroje.
Další kroky
V tomto kurzu jste:
- Zjistili jsme, jak načíst související data.
- Vytvoření stránky Kurzy
- Vytvoření stránky instruktorů
V dalším článku se dozvíte, jak aktualizovat související data.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro