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 Frameworku a SQL Serveru LocalDB. V tomto kurzu si projdete 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

Je to běžný postup implementace vzoru úložiště za účelem vytvoření abstrakční vrstvy mezi kontrolerem a vrstvou přístupu k datům. Aby byly tyto kurzy jednoduché a zaměřené na výuku použití samotné entity Frameworku, 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 jste:

  • Přizpůsobení stránky Podrobnosti
  • Aktualizace stránky Vytvořit
  • Aktualizace stránky Upravit
  • Aktualizace stránky Odstranit
  • Zavření databázových připojení

Požadavky

Přizpůsobení stránky Podrobnosti

Vygenerovaný kód stránky 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.csakce pro zobrazení Podrobnosti používá metodu FirstOrDefaultAsync k načtení jedné Student entity. Přidejte kód, který volá Include. ThenIncludea 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 způsobují ThenInclude , že kontext načte Student.Enrollments navigační vlastnost a v rámci každé registrace Enrollment.Course navigační vlastnost. 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á Details metodě pochází z dat směrování. Směrovací data jsou data, která pořadač modelů našli 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; tyto hodnoty jsou směrované datové hodnoty.

http://localhost:1230/Instructor/Index/1?courseID=2021

Poslední část adresy URL ("?courseID=2021") je hodnota řetězce dotazu. Pokud ji předáte jako řetězcovou hodnotu dotazu, předá pořadač modelu také hodnotu ID parametru Index metody id :

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 dat trasy.

<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ýchrutinch ASP.NET ch

Přidání registrací do zobrazení Podrobností

Otevřete Views/Students/Details.cshtml. Každé pole se zobrazí pomocí DisplayNameFor a DisplayFor pomocných rutin, 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 pravou </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í entity v Enrollments navigační vlastnosti. U každé registrace 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 Enrollments.

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:

Student Details page

Aktualizace stránky Vytvořit

Upravte StudentsController.csmetodu HttpPost Create přidáním bloku try-catch a odebráním 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 pořadačem 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 odesílaný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č modelu vytvoří instanci entity Student pro 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 automaticky nastaví při vložení řádku. Vstup od uživatele nenastaví hodnotu ID.

Kromě atributu Bind je blok try-catch jedinou změnou, kterou jste provedli v kódu vygenerovaného uživatelského rozhraní. 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 externím než programovací chybou aplikace, takže se uživateli doporučuje zkusit to znovu. I když není v této ukázce implementováno, aplikace pro kvalitu produkce zaznamená výjimku. Další informace najdete v části Protokol pro přehled v tématu Monitorování a telemetrie (vytváření Real-World Cloud Apps pomocí Azure).

Atribut ValidateAntiForgeryToken pomáhá zabránit útokům na žádost mezi weby (CSRF). Token se automaticky vloží do zobrazení pomocí FormTagHelper a je zahrnut při odeslání formuláře uživatelem. Token se ověří atributem ValidateAntiForgeryToken . Další informace najdete v tématu Prevence útoků XSRF/CSRF (Cross-Site Request Forgery) v ASP.NET Core.

Poznámka k zabezpečení týkající se nadměrného umístění

Atribut Bind , který 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, hacker by mohl použít nástroj, jako je Fiddler, nebo napsat nějaký JavaScript a publikovat Secret hodnotu formuláře. Bez atributu Bind omezujících pole, která pořadač modelu používá při vytváření instance Student, by pořadač modelu vyzvedne tuto Secret hodnotu formuláře a použije ji k vytvoření instance entity Student. Pak by se v databázi aktualizovala jakákoli hodnota, kterou hacker zadal pro Secret pole formuláře. Na následujícím obrázku je nástroj Fiddler, který přidá Secret pole (s hodnotou OverPost) k publikovaným hodnotám formuláře.

Fiddler adding Secret field

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.

Můžete zabránit přeúčtování ve scénářích úprav tak, že nejprve přečtete entitu z databáze a potom zavoláte a předáte TryUpdateModelexplicitní seznam povolených vlastností. To je metoda použitá v těchto kurzech.

Alternativním způsobem, jak zabránit nadměrnému umístění, 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 jenom 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 například AutoMapper. Pomocí _context.Entry instance entity nastavíte její stav na Unchangedhodnotu Property("PropertyName").IsModified true pro každou vlastnost entity, která je součástí modelu zobrazení. Tato metoda funguje ve scénářích úprav a vytváření.

Otestování stránky Vytvořit

Kód v Views/Students/Create.cshtml pomocných labelrutinách značek , inputa span (pro ověřovací zprávy) pro každé pole.

Spusťte aplikaci, vyberte kartu Studenti a klikněte na Vytvořit nový.

Zadejte jména a datum. Pokud to váš prohlížeč umožňuje, zkuste zadat neplatné datum. (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.

Date validation error

Toto je ověřování na straně serveru, které se vám ve výchozím nastavení zobrazí; V pozdějším kurzu se dozvíte, jak přidat atributy, které vygenerují kód pro ověření 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 zobrazíte nového studenta na stránce Index .

Aktualizace stránky Upravit

V StudentController.cs, HttpGet Edit metoda (to bez atributu HttpPost ) používá metodu FirstOrDefaultAsync k načtení vybrané student entity, jak jste viděli Details v metodě. Tuto metodu nemusíte měnit.

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 existující data v polích, která nejsou uvedená v parametru Include .

Nový kód nač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 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. (V pozdějším kurzu se dozvíte, jak řešit konflikty souběžnosti.)

Osvědčeným postupem, jak zabránit přeúčtová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č modelu svázat, zajistí, že pokud do datového modelu přidáte pole 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; proto jste metodu EditPostpřejmenovali .

Alternativní kód pro úpravy 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. (Neaktualizujete projekt pomocí tohoto kódu, zobrazí se jenom nepovinný přístup.)

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á přístup k vytvoření a připojení, ale zachytí DbUpdateConcurrencyException pouze výjimky a vrátí 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 jsou entity v paměti synchronizované s odpovídajícími řádky v databázi a tyto informace určují, co se stane při volání SaveChanges metody. Například když do metody předáte novou entitu Add , je stav dané entity nastavený na Added. Při volání SaveChanges metody pak kontext databáze vydá příkaz SQL INSERT.

Entita může být v jednom z následujících stavů:

  • Added. Entita ještě v databázi neexistuje. Metoda SaveChanges vydává příkaz INSERT.

  • Unchanged. S touto entitou není potřeba nic dělat metodou SaveChanges . 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. Metoda SaveChanges vydává příkaz UPDATE.

  • Deleted. Entita byla označena k odstranění. Metoda SaveChanges vydává příkaz DELETE.

  • Detached. Entita není sledována kontextem databáze.

V desktopové aplikaci se změny stavu obvykle nastavují 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. Když pak zavoláte SaveChanges, Entity Framework vygeneruje příkaz SQL UPDATE, který aktualizuje pouze skutečné vlastnosti, které jste změnili.

Ve webové aplikaci, která původně čte entitu a zobrazuje její data, která se mají upravit, DbContext se odstraní po vykreslení stránky. Při volání metody akce HttpPost Edit se vytvoří nový webový požadavek a máte novou instanci DbContext. Pokud entitu v tomto novém kontextu znovu přečtete, simulujete zpracování plochy.

Pokud ale nechcete provádět další operace č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 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á způsob, jak zjistit, které vlastnosti jste změnili.

Pokud se chcete vyhnout přístupu 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 volá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 pak volat SaveChanges.

Otestování stránky Pro úpravy

Spusťte aplikaci, vyberte kartu Studenti a potom klikněte na odkaz Upravit .

Students edit page

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é entity Student, jak jste viděli v metodách Details a Edit. Pokud ale chcete implementovat vlastní chybovou zprávu při selhání volání SaveChanges , přidáte do této metody některé funkce a odpovídající zobrazení.

Jak jste viděli pro operace aktualizace a vytváření, operace odstranění vyžadují dvě metody akce. Metoda, která je volána v reakci na požadavek GET, zobrazí zobrazení, které uživateli umožní schválit nebo zrušit operaci odstranění. Pokud ho uživatel schválí, vytvoří se žádost POST. V takovém případě se volá metoda HttpPost Delete a pak tato metoda skutečně provede 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ává ji 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 poskytne 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, jestli 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 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 zvýšení výkonu v aplikaci s vysokým objemem priorita, můžete se vyhnout nepotřebným dotazům SQL tím, že vytvoříte instanci entity Student pouze pomocí hodnoty primárního klíče a pak nastavíte stav entity na Deleted. 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í být jasné, že existují související entity, které se mají odstranit.

Aktualizace zobrazení Odstranit

V Views/Student/Delete.cshtmlčásti přidejte chybovou zprávu mezi nadpisem h2 a nadpisem 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:

Delete confirmation page

Klikněte na Odstranit. Stránka Index se zobrazí bez odstraněného studenta. (V kurzu souběžnosti se zobrazí 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 kontextová instance co nejdříve odstraněna, jakmile s ní budete hotovi. Integrované injektáže závislostí core ASP.NET se postará o tuto úlohu za vás.

V Startup.cs, zavoláte AddDbContext rozšiřující metodu pro zřízení DbContext třídy v kontejneru ASP.NET Core DI. Tato metoda nastaví životnost služby ve Scoped výchozím nastavení. Scoped znamená, že doba životnosti kontextového objektu se shoduje s dobou životnosti webové žádosti a Dispose metoda bude volána 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 pak 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 nejprve dokončí a pak dojde k chybě, tyto změny se automaticky vrátí zpět. V situacích, kdy potřebujete větší kontrolu – například pokud chcete zahrnout operace provedené mimo Entity Framework do transakce – 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 tím, co je 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, je obvykle odstraněn 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. Typické scénáře, ve kterých byste mohli chtít provést následující:

  • Během doby života kontextu nemusíte aktualizovat žádné entity a nemusíte ef automaticky načítat vlastnosti navigace 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 načetli 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 zvládnout, je volat AsNoTracking starší dotaz.

Další informace naleznete v tématu Sledování vs. No-Tracking.

Získání kódu

Stáhněte nebo zobrazte dokončenou aplikaci.

Další kroky

V tomto kurzu jste:

  • Přizpůsobená stránka Podrobnosti
  • 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 Index přidáním řazení, filtrování a stránkování.