Kurz: Implementace funkcí CRUD – ASP.NET MVC s EF Core
V předchozím kurzu jste vytvořili aplikaci MVC, která ukládá a zobrazuje data pomocí Entity Framework a SQL Server LocalDB. V tomto kurzu zkontrolujete a přizpůsobíte kód CRUD (vytvoření, čtení, aktualizace, odstranění), který automaticky vytvoří generování MVC v řadičích a zobrazeních.
Poznámka
Běžným postupem je implementovat vzor úložiště, abyste vytvořili abstraktní vrstvu mezi kontrolerem a vrstvou přístupu k datům. Aby byly tyto kurzy jednoduché a zaměřené na výuku, jak používat samotné entity Framework, nepoužívají úložiště. Informace o úložištích s EF najdete v posledním kurzu této série.
V tomto kurzu se naučíte:
- Přizpůsobení stránky Podrobnosti
- Aktualizace stránky Vytvořit
- Aktualizace stránky Upravit
- Aktualizace stránky Odstranit
- Zavření připojení k databázi
Požadavky
Přizpůsobení stránky Podrobnosti
Vygenerovaný kód pro stránku Index studentů opustil Enrollments
vlastnost, protože tato vlastnost obsahuje kolekci. Na stránce Podrobnosti zobrazíte obsah kolekce v tabulce HTML.
Metoda Controllers/StudentsController.cs
akce pro zobrazení Podrobností používá metodu FirstOrDefaultAsync
k načtení jedné Student
entity. Přidejte kód, který volá Include
. ThenInclude
a AsNoTracking
metody, jak je znázorněno v následujícím zvýrazněném kódu.
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Students
.Include(s => s.Enrollments)
.ThenInclude(e => e.Course)
.AsNoTracking()
.FirstOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
return View(student);
}
Metody Include
a ThenInclude
kontext způsobují načtení Student.Enrollments
navigační vlastnosti a v rámci každé registrace Enrollment.Course
navigační vlastnosti. Další informace o těchto metodách najdete v kurzu čtení souvisejících dat .
Tato AsNoTracking
metoda zlepšuje výkon ve scénářích, kdy se vrácené entity nebudou aktualizovat v době života aktuálního kontextu. Další AsNoTracking
informace najdete na konci tohoto kurzu.
Směrování dat
Hodnota klíče předaná metodě Details
pochází ze směrovacích dat. Směrovací data jsou data, která pořadač modelů našel v segmentu adresy URL. Výchozí trasa například určuje segmenty kontroleru, akce a ID:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
V následující adrese URL výchozí trasa mapuje instruktora jako kontroler, index jako akci a 1 jako ID; jedná se o směrovací hodnoty dat.
http://localhost:1230/Instructor/Index/1?courseID=2021
Poslední část adresy URL ("?courseID=2021") je hodnota řetězce dotazu. Pořadač modelů také předá hodnotu ID parametru Index
metody id
, pokud ji předáte jako hodnotu řetězce dotazu:
http://localhost:1230/Instructor/Index?id=1&CourseID=2021
Na stránce Index se adresy URL hypertextových odkazů vytvářejí pomocí pomocných příkazů značek v Razor zobrazení. V následujícím Razor kódu id
se parametr shoduje s výchozí trasou, takže id
se přidá do směrovacích dat.
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a>
Tím se vygeneruje následující kód HTML, pokud item.ID
je 6:
<a href="/Students/Edit/6">Edit</a>
V následujícím Razor kódu studentID
neodpovídá parametru ve výchozí trase, takže se přidá jako řetězec dotazu.
<a asp-action="Edit" asp-route-studentID="@item.ID">Edit</a>
Tím se vygeneruje následující kód HTML, pokud item.ID
je 6:
<a href="/Students/Edit?studentID=6">Edit</a>
Další informace o pomocných rutinách značek najdete v tématu Pomocné rutiny značek v ASP.NET Core.
Přidání registrací do zobrazení Podrobností
Otevře záznam typu Views/Students/Details.cshtml
. Každé pole se zobrazí pomocí DisplayNameFor
a DisplayFor
pomocné rutiny, jak je znázorněno v následujícím příkladu:
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.LastName)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.LastName)
</dd>
Za poslední pole a bezprostředně před koncovou </dl>
značku přidejte následující kód, který zobrazí seznam registrací:
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Enrollments)
</dt>
<dd class="col-sm-10">
<table class="table">
<tr>
<th>Course Title</th>
<th>Grade</th>
</tr>
@foreach (var item in Model.Enrollments)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Course.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.Grade)
</td>
</tr>
}
</table>
</dd>
Pokud je odsazení kódu po vložení kódu chybné, opravte ho stisknutím kláves CTRL-K-D.
Tento kód prochází entitami v Enrollments
navigační vlastnosti. Pro každou registraci se zobrazí název kurzu a známka. Název kurzu se načte z entity kurzu, která je uložená v Course
navigační vlastnosti entity Registrace.
Spusťte aplikaci, vyberte kartu Studenti a klikněte na odkaz Podrobnosti pro studenta. Zobrazí se seznam kurzů a známek pro vybraného studenta:
Aktualizace stránky Vytvořit
V StudentsController.cs
, upravit HttpPost Create
metoda přidáním try-catch bloku a odebrání ID z atributu Bind
.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
[Bind("EnrollmentDate,FirstMidName,LastName")] Student student)
{
try
{
if (ModelState.IsValid)
{
_context.Add(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists " +
"see your system administrator.");
}
return View(student);
}
Tento kód přidá entitu Student vytvořenou vazbu modelu ASP.NET Core MVC do sady entit Students a uloží změny do databáze. (Pořadač modelů odkazuje na funkci ASP.NET Core MVC, která usnadňuje práci s daty odeslanými formulářem. Pořadač modelu převede publikované hodnoty formuláře na typy CLR a předá je metodě akce v parametrech. V tomto případě pořadač modelů vytvoří instanci entity Student za vás pomocí hodnot vlastností z kolekce Formulářů.)
Odebrali ID
jste z atributu Bind
, protože ID je hodnota primárního klíče, kterou SQL Server nastaví automaticky při vložení řádku. Vstup od uživatele nenastaví hodnotu ID.
Kromě atributu Bind
je blok try-catch jedinou změnou kódu, kterou jste provedli vygenerovaný kód. Pokud je při ukládání změn zachycena výjimka odvozená od DbUpdateException
změn, zobrazí se obecná chybová zpráva. DbUpdateException
Výjimky jsou někdy způsobeny něčím, co není externí aplikací, a ne programovací chybou, takže uživateli doporučujeme zkusit to znovu. I když není v této ukázce implementováno, aplikace v produkční kvalitě zaznamená výjimku. Další informace najdete v části Protokol pro přehled v tématu Monitorování a telemetrie (vytváření reálných cloudových aplikací pomocí Azure).
Tento ValidateAntiForgeryToken
atribut pomáhá zabránit útokům csrF (cross-site request forgery). Token se automaticky vloží do zobrazení formTagHelper a je zahrnut při odeslání formuláře uživatelem. Token je ověřen atributem ValidateAntiForgeryToken
. Další informace najdete v tématu Prevence útoků založených na padělání žádosti posílané mezi weby (XSRF/CSRF) v ASP.NET Core.
Poznámka k zabezpečení týkající se nadměrného umístění
Atribut Bind
, který kód vygenerovaný vygenerovaný kód obsahuje v Create
metodě, je jedním ze způsobů, jak chránit před nadměrném umístěním ve scénářích vytváření. Předpokládejme například, že entita Student obsahuje Secret
vlastnost, kterou nechcete, aby tato webová stránka byla nastavena.
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public string Secret { get; set; }
}
I když nemáte Secret
pole na webové stránce, mohl by hacker použít nástroj, jako je Fiddler, nebo napsat nějaký JavaScript, k publikování Secret
hodnoty formuláře. Bind
Bez omezení atributů pole, která binder modelu používá při vytváření instance Student, by pořadač modelu tuto hodnotu formuláře vyzvedá Secret
a použil ho k vytvoření instance entity Student. Pak by se ve vaší databázi aktualizovala jakákoli hodnota, kterou hacker zadal pro Secret
pole formuláře. Následující obrázek ukazuje nástroj Fiddler, který přidává Secret
pole (s hodnotou OverPost) do odeslaných hodnot formuláře.
Hodnota OverPost by se pak úspěšně přidala do Secret
vlastnosti vloženého řádku, i když jste nikdy nechtěli, aby webová stránka mohla tuto vlastnost nastavit.
Pokud chcete zabránit přesílání v editačních scénářích, můžete nejprve přečíst entitu z databáze a potom zavolat TryUpdateModel
a předat explicitní seznam povolených vlastností. To je metoda použitá v těchto kurzech.
Alternativní způsob, jak zabránit nadměrnému příspěvku, který upřednostňuje mnoho vývojářů, je použít modely zobrazení místo tříd entit s vazbou modelu. Do modelu zobrazení zahrňte pouze vlastnosti, které chcete aktualizovat. Po dokončení pořadače modelu MVC zkopírujte vlastnosti modelu zobrazení do instance entity, volitelně pomocí nástroje, jako je automapper. Pomocí _context.Entry
instance entity můžete nastavit jeho stav na Unchanged
hodnotu a pak nastavit Property("PropertyName").IsModified
hodnotu true u každé vlastnosti entity, která je součástí modelu zobrazení. Tato metoda funguje ve scénářích pro úpravy i vytváření.
Otestování stránky Vytvořit
Pomocné rutiny značek pro jednotlivá pole používá label
kód Views/Students/Create.cshtml
a input
span
(pro ověřovací zprávy).
Spusťte aplikaci, vyberte kartu Studenti a klikněte na Vytvořit nový.
Zadejte jména a datum. Zkuste zadat neplatné datum, pokud vám to prohlížeč umožní. (Některé prohlížeče vás přinutí použít výběr data.) Potom kliknutím na Vytvořit zobrazíte chybovou zprávu.
Jedná se o ověřování na straně serveru, které získáte ve výchozím nastavení; V pozdějším kurzu se dozvíte, jak přidat atributy, které vygenerují kód pro ověřování na straně klienta. Následující zvýrazněný kód ukazuje kontrolu ověření modelu v Create
metodě.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
[Bind("EnrollmentDate,FirstMidName,LastName")] Student student)
{
try
{
if (ModelState.IsValid)
{
_context.Add(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists " +
"see your system administrator.");
}
return View(student);
}
Změňte datum na platnou hodnotu a kliknutím na Vytvořit zobrazte nového studenta na stránce Rejstřík .
Aktualizace stránky Upravit
V StudentController.cs
, HttpGet Edit
metoda (ten bez atributu HttpPost
) používá FirstOrDefaultAsync
metodu k načtení vybrané Student entity, jak jste viděli Details
v metodě. Tuto metodu nemusíte měnit.
Doporučený kód HttpPost Edit: Čtení a aktualizace
Nahraďte metodu akce HttpPost Edit následujícím kódem.
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditPost(int? id)
{
if (id == null)
{
return NotFound();
}
var studentToUpdate = await _context.Students.FirstOrDefaultAsync(s => s.ID == id);
if (await TryUpdateModelAsync<Student>(
studentToUpdate,
"",
s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate))
{
try
{
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " +
"see your system administrator.");
}
}
return View(studentToUpdate);
}
Tyto změny implementují osvědčený postup zabezpečení, aby se zabránilo nadměrnému umístění. Scaffolder vygeneroval Bind
atribut a přidal entitu vytvořenou pořadačem modelu do sady entit s příznakem Modified
. Tento kód se nedoporučuje pro mnoho scénářů, protože Bind
atribut vymaže všechna předem existující data v polích, která nejsou uvedená v parametru Include
.
Nový kód přečte existující entitu a volání TryUpdateModel
pro aktualizaci polí v načtené entitě na základě uživatelského vstupu v publikovaných datech formuláře. Automatické sledování změn entity Framework nastaví Modified
příznak u polí, která se mění vstupem formuláře. SaveChanges
Při volání metody Entity Framework vytvoří příkazy SQL pro aktualizaci řádku databáze. Konflikty souběžnosti se ignorují a v databázi se aktualizují jenom sloupce tabulky, které uživatel aktualizoval. (Další kurz ukazuje, jak řešit konflikty souběžnosti.)
Osvědčeným postupem, jak zabránit nadměrnému umístění, jsou pole, která chcete aktualizovat stránkou Upravit , deklarována v parametrech TryUpdateModel
. (Prázdný řetězec, který předchází seznamu polí v seznamu parametrů, je předpona, která se má použít s názvy polí formuláře.) V současné době nejsou k dispozici žádná další pole, která chráníte, ale výpis polí, která má pořadač modelů svázat, zajistí, že pokud přidáte pole do datového modelu v budoucnu, budou automaticky chráněná, dokud je sem explicitně nepřidáte.
V důsledku těchto změn je podpis metody HttpPost Edit
metoda stejný jako HttpGet Edit
metoda, a proto jste metodu EditPost
přejmenovali .
Alternativní kód pro úpravu httppostu: Vytvoření a připojení
Doporučený kód pro úpravy HttpPost zajišťuje, že se aktualizují jenom změněné sloupce a zachová data ve vlastnostech, které nechcete zahrnout do vazby modelu. Přístup pro čtení ale vyžaduje další čtení databáze a může vést ke složitějšímu kódu pro zpracování konfliktů souběžnosti. Alternativou je připojit entitu vytvořenou pořadačem modelu k kontextu EF a označit ji jako upravenou. (Neaktualizovat projekt tímto kódem, zobrazí se pouze pro ilustraci volitelného přístupu.)
public async Task<IActionResult> Edit(int id, [Bind("ID,EnrollmentDate,FirstMidName,LastName")] Student student)
{
if (id != student.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " +
"see your system administrator.");
}
}
return View(student);
}
Tento přístup můžete použít, když uživatelské rozhraní webové stránky obsahuje všechna pole v entitě a může je aktualizovat.
Vygenerovaný kód používá metodu create-and-attach, ale zachytává DbUpdateConcurrencyException
pouze výjimky a vrací kódy chyb 404. Zobrazený příklad zachytí výjimku aktualizace databáze a zobrazí chybovou zprávu.
Stavy entit
Kontext databáze sleduje, jestli se entity v paměti synchronizují s odpovídajícími řádky v databázi a tyto informace určují, co se stane při volání SaveChanges
metody. Když například předáte do metody novou entitu Add
, stav této entity je nastaven na Added
. Když pak zavoláte metodu SaveChanges
, kontext databáze vydá příkaz SQL INSERT.
Entita může být v jednom z následujících stavů:
Added
. Entita v databázi ještě neexistuje. MetodaSaveChanges
vydá příkaz INSERT.Unchanged
. Metodou není potřeba s touto entitouSaveChanges
nic dělat. Při čtení entity z databáze začne entita s tímto stavem.Modified
. Některé nebo všechny hodnoty vlastností entity byly změněny. MetodaSaveChanges
vydává příkaz UPDATE.Deleted
. Entita byla označena k odstranění. MetodaSaveChanges
vydá příkaz DELETE.Detached
. Entita není sledována kontextem databáze.
V desktopové aplikaci se změny stavu obvykle nastaví automaticky. Přečtete entitu a provedete změny některých hodnot jeho vlastností. To způsobí, že se stav entity automaticky změní na Modified
. Při volání SaveChanges
Entity Framework vygeneruje příkaz SQL UPDATE, který aktualizuje pouze skutečné vlastnosti, které jste změnili.
Ve webové aplikaci, která původně přečte entitu a zobrazí její data, která se mají upravit, DbContext
se odstraní po vykreslení stránky. Když je volána metoda akce HttpPost Edit
, vytvoří se nový webový požadavek a máte novou instanci DbContext
. Pokud entitu znovu přečtete v tomto novém kontextu, simulujete zpracování plochy.
Pokud ale nechcete provádět další operaci čtení, musíte použít objekt entity vytvořený pořadačem modelu. Nejjednodušším způsobem, jak to udělat, je nastavit stav entity na Změněno, jak je to provedeno v alternativním kódu HttpPost Edit zobrazeném dříve. Když pak zavoláte SaveChanges
, Entity Framework aktualizuje všechny sloupce řádku databáze, protože kontext nemá žádný způsob, jak zjistit, které vlastnosti jste změnili.
Pokud se chcete vyhnout přístupu jen pro čtení, ale chcete, aby příkaz SQL UPDATE aktualizoval pouze pole, která uživatel skutečně změnil, je kód složitější. Původní hodnoty musíte uložit nějakým způsobem (například pomocí skrytých polí), aby byly k dispozici při zavolání metody HttpPost Edit
. Pak můžete vytvořit entitu Student pomocí původních hodnot, volat metodu Attach
s původní verzí entity, aktualizovat hodnoty entity na nové hodnoty a potom volat SaveChanges
.
Otestování stránky Upravit
Spusťte aplikaci, vyberte kartu Studenti a klikněte na hypertextový odkaz Pro úpravy .
Změňte některá data a klikněte na Uložit. Otevře se stránka Index a zobrazí se změněná data.
Aktualizace stránky Odstranit
Kód StudentController.cs
šablony pro metodu HttpGet Delete
používá metodu FirstOrDefaultAsync
k načtení vybrané student entity, jak jste viděli v Metodách Details a Edit. Pokud ale chcete implementovat vlastní chybovou zprávu v případě selhání volání SaveChanges
, přidáte do této metody některé funkce a odpovídající zobrazení.
Jak jste viděli o operacích aktualizace a vytváření, operace odstranění vyžadují dvě metody akcí. Metoda, která je volána v reakci na požadavek GET, zobrazí zobrazení, které uživateli umožňuje schválit nebo zrušit operaci odstranění. Pokud ho uživatel schválí, vytvoří se žádost POST. V takovém případě je volána metoda HttpPost Delete
a pak tato metoda ve skutečnosti provádí operaci odstranění.
Do metody HttpPost Delete
přidáte blok try-catch, který zpracuje případné chyby, ke kterým může dojít při aktualizaci databáze. Pokud dojde k chybě, Metoda HttpPost Delete volá metodu HttpGet Delete a předá jí parametr, který označuje, že došlo k chybě. Metoda HttpGet Delete pak znovu zobrazí potvrzovací stránku spolu s chybovou zprávou, která uživateli dává příležitost zrušit nebo zkusit znovu.
Nahraďte metodu akce HttpGet Delete
následujícím kódem, který spravuje hlášení chyb.
public async Task<IActionResult> Delete(int? id, bool? saveChangesError = false)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Students
.AsNoTracking()
.FirstOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
if (saveChangesError.GetValueOrDefault())
{
ViewData["ErrorMessage"] =
"Delete failed. Try again, and if the problem persists " +
"see your system administrator.";
}
return View(student);
}
Tento kód přijímá volitelný parametr, který označuje, zda byla metoda volána po selhání uložení změn. Tento parametr je false, pokud je volána Metoda HttpGet Delete
bez předchozího selhání. Když je volána metodou HttpPost Delete
v reakci na chybu aktualizace databáze, parametr je pravdivý a chybová zpráva se předá zobrazení.
Přístup pro čtení k odstranění httpPostu
Nahraďte metodu akce HttpPost Delete
(pojmenovanou DeleteConfirmed
) následujícím kódem, který provádí skutečnou operaci odstranění a zachytí všechny chyby aktualizace databáze.
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var student = await _context.Students.FindAsync(id);
if (student == null)
{
return RedirectToAction(nameof(Index));
}
try
{
_context.Students.Remove(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
Tento kód načte vybranou entitu a potom zavolá metodu Remove
, která nastaví stav entity na Deleted
. Při SaveChanges
volání se vygeneruje příkaz SQL DELETE.
Přístup k vytvoření a připojení k odstranění httpPostu
Pokud je prioritou zvýšení výkonu ve vysokoobjemové aplikaci, můžete se vyhnout zbytečnému dotazu SQL tak, že vytvoříte instanci entity Studenta pouze s hodnotou primárního klíče a pak nastavíte stav entity na Deleted
hodnotu . To je vše, co Entity Framework potřebuje k odstranění entity. (Nevkládejte tento kód do projektu. Tady je jenom ilustrace alternativy.)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
try
{
Student studentToDelete = new Student() { ID = id };
_context.Entry(studentToDelete).State = EntityState.Deleted;
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
Pokud entita obsahuje související data, která by se měla také odstranit, ujistěte se, že je v databázi nakonfigurované kaskádové odstranění. Díky tomuto přístupu k odstranění entity ef nemusí dojít k odstranění souvisejících entit.
Aktualizace zobrazení Odstranit
Do Views/Student/Delete.cshtml
pole , přidejte chybovou zprávu mezi nadpis h2 a nadpis h3, jak je znázorněno v následujícím příkladu:
<h2>Delete</h2>
<p class="text-danger">@ViewData["ErrorMessage"]</p>
<h3>Are you sure you want to delete this?</h3>
Spusťte aplikaci, vyberte kartu Studenti a klikněte na odstranit hypertextový odkaz:
Klepněte na tlačítko Odstranit. Stránka Rejstříku se zobrazí bez odstraněného studenta. (V kurzu souběžnosti uvidíte příklad kódu zpracování chyb v akci.)
Zavření připojení k databázi
Pokud chcete uvolnit prostředky, které obsahuje připojení k databázi, musí být instance kontextu co nejdříve odstraněna, jakmile s ní budete hotovi. O tuto úlohu se postará integrované injektáž závislostí ASP.NET Core.
V Startup.cs
volání AddDbContext rozšiřující metoda zřídit DbContext
třídu v kontejneru ASP.NET Core DI. Tato metoda nastaví životnost služby ve Scoped
výchozím nastavení. Scoped
znamená, že životnost kontextového objektu se shoduje s dobou životnosti webového požadavku a Dispose
metoda se bude volat automaticky na konci webového požadavku.
Zpracování transakcí
Ve výchozím nastavení Entity Framework implicitně implementuje transakce. Ve scénářích, ve kterých provedete změny v několika řádcích nebo tabulkách a potom zavoláte SaveChanges
, entity Framework automaticky zajistí, aby všechny vaše změny proběhly úspěšně nebo všechny selžou. Pokud se některé změny dokončí nejprve a dojde k chybě, tyto změny se automaticky vrátí zpět. Scénáře, ve kterých potřebujete větší kontrolu – například pokud chcete zahrnout operace provedené mimo Entity Framework v transakci – viz Transakce.
Dotazy bez sledování
Když kontext databáze načte řádky tabulky a vytvoří objekty entity, které je představují, ve výchozím nastavení sleduje, jestli jsou entity v paměti synchronizované s objekty v databázi. Data v paměti fungují jako mezipaměť a používají se při aktualizaci entity. Ukládání do mezipaměti je často ve webové aplikaci zbytečné, protože kontextové instance jsou obvykle krátkodobé (pro každý požadavek se vytvoří a odstraní nový) a kontext, který čte entitu, se obvykle odstraní před tím, než se tato entita znovu použije.
Sledování objektů entity v paměti můžete zakázat voláním AsNoTracking
metody. Mezi typické scénáře, ve kterých můžete chtít provést následující:
Během doby života kontextu nemusíte aktualizovat žádné entity a nemusíte ef automaticky načítat navigační vlastnosti s entitami načtenými samostatnými dotazy. Tyto podmínky jsou často splněny v metodách akcí HttpGet kontroleru.
Spouštíte dotaz, který načte velký objem dat a aktualizuje se pouze malá část vrácených dat. Sledování velkého dotazu může být efektivnější vypnout a později spustit dotaz pro několik entit, které je potřeba aktualizovat.
Chcete připojit entitu, abyste ji mohli aktualizovat, ale dříve jste získali stejnou entitu pro jiný účel. Vzhledem k tomu, že entita je již sledována kontextem databáze, nemůžete připojit entitu, kterou chcete změnit. Jedním ze způsobů, jak tuto situaci zpracovat, je volání
AsNoTracking
předchozího dotazu.
Další informace naleznete v tématu Sledování vs. Bez sledování.
Získání kódu
Stáhněte nebo zobrazte dokončenou aplikaci.
Další kroky
V tomto kurzu se naučíte:
- Přizpůsobená stránka Podrobností
- Aktualizace stránky Vytvořit
- Aktualizace stránky Upravit
- Aktualizace stránky Odstranit
- Uzavřená připojení k databázi
V dalším kurzu se dozvíte, jak rozšířit funkce stránky Rejstřík přidáním řazení, filtrování a stránkování.