Sdílet prostřednictvím


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.csakce pro zobrazení Podrobností 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 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:

Student Details page

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.

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.

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 TryUpdateModela 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 Unchangedhodnotu 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á labelkód Views/Students/Create.cshtml a inputspan (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.

Date validation error

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.

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 EditPostpř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. Metoda SaveChanges vydá příkaz INSERT.

  • Unchanged. Metodou není potřeba s touto entitou SaveChanges 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. Metoda SaveChanges vydává příkaz UPDATE.

  • Deleted. Entita byla označena k odstranění. Metoda SaveChanges 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í SaveChangesEntity 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 .

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é 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 Deletedhodnotu . 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.cshtmlpole , 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:

Delete confirmation page

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.csvolá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í.