Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Při dotazování můžete číst data z databáze, ukládání dat znamená přidávání nových entit do databáze, odebírání entit nebo úpravy vlastností existujících entit nějakým způsobem. Entity Framework Core (EF Core) podporuje dva základní přístupy pro ukládání dat do databáze.
Přístup 1: sledování změn a metoda SaveChanges
V mnoha scénářích musí váš program dotazovat některá data z databáze, provést některé úpravy a uložit tyto změny zpět; někdy se označuje jako "jednotka práce". Předpokládejme například, že máte sadu blogů a chcete změnit Url
vlastnost jednoho z nich. V EF se to obvykle provádí takto:
using (var context = new BloggingContext())
{
var blog = await context.Blogs.SingleAsync(b => b.Url == "http://example.com");
blog.Url = "http://example.com/blog";
await context.SaveChangesAsync();
}
Výše uvedený kód provede následující kroky:
- Používá k načtení entity z databáze běžný dotaz LINQ (viz dotazování dat). Dotazy EF ve výchozím nastavení používají sledování, což znamená, že EF sleduje načtené entity ve svém interním sledovačem změn.
- Načtená instance entity se manipuluje obvyklým způsobem přiřazením vlastnosti .NET. Ef není součástí tohoto kroku.
- Nakonec se zavolá DbContext.SaveChanges(). V tomto okamžiku EF automaticky rozpozná všechny změny porovnáním entit se snímkem od okamžiku, kdy byly načteny. Všechny zjištěné změny se uchovávají v databázi; Při použití relační databáze to obvykle zahrnuje odesílání, například SQL
UPDATE
, aby se aktualizovaly příslušné řádky.
Všimněte si, že výše byla popsána typická operace aktualizace pro existující data, avšak podobné principy platí i pro přidávání a odebírání entit. Se sledováním změn EF komunikujete voláním DbSet<TEntity>.Add a Remove, což způsobuje sledování změn. EF pak použije všechny sledované změny databáze při SaveChanges() volání (např. prostřednictvím SQL INSERT
a DELETE
při použití relační databáze).
SaveChanges() nabízí následující výhody:
- Nemusíte psát kód pro sledování, které entity a vlastnosti se změnily – EF to udělá automaticky za vás a aktualizuje pouze tyto vlastnosti v databázi, což zlepšuje výkon. Představte si, jestli jsou načtené entity svázané s komponentou uživatelského rozhraní, což uživatelům umožňuje změnit libovolnou vlastnost, kterou chtějí. EF odloží zátěž zjištění, které entity a vlastnosti byly skutečně změněny.
- Ukládání změn do databáze může být někdy složité. Pokud například chcete přidat blog a některé příspěvky pro tento blog, možná budete muset načíst klíč vygenerovaný databází pro vložený blog předtím, než budete moct vložit příspěvky (protože potřebují odkazovat na blog). EF to všechno udělá za vás a zbaví složitosti.
- EF může detekovat problémy se souběžností, například když někdo jiný změnil řádek databáze mezi vaším dotazem a SaveChanges(). Další podrobnosti jsou k dispozici v konfliktech souběžnosti.
- V databázích, které ji podporují, SaveChanges() automaticky zabalí více změn v transakci, aby vaše data zůstala konzistentní, pokud dojde k selhání. Další podrobnosti jsou k dispozici v transakcích.
- SaveChanges() také seskupuje několik změn v mnoha případech, výrazně snižuje počet opakovaných pokusů databáze a výrazně zlepšuje výkon. Další podrobnosti jsou k dispozici v oblasti efektivní aktualizace.
Další informace a ukázky kódu týkající se základního SaveChanges() použití najdete v tématu Basic SaveChanges. Další informace o sledování změn EF najdete v přehledu sledování změn.
Přístup 2: ExecuteUpdate a ExecuteDelete ("hromadná aktualizace")
Sledování změn a také SaveChanges() jsou výkonným způsobem, jak uložit změny, ale mají také určité nevýhody.
Nejprve je nezbytné, aby SaveChanges() vyžadoval dotazování a sledování všech entit, které budete upravovat nebo odstraňovat. Pokud potřebujete odstranit všechny blogy s hodnocením pod určitou prahovou hodnotou, musíte dotazovat, materializovat a sledovat potenciálně velký počet řádků a vygenerovat SaveChanges()DELETE
příkaz pro každý z nich. Relační databáze poskytují mnohem efektivnější alternativu: lze odeslat jeden DELETE
příkaz, určit řádky, které se mají odstranit prostřednictvím WHERE
klauzule, ale SaveChanges() model to neumožňuje generovat.
Pro podporu tohoto scénáře hromadné aktualizace můžete použít následující:ExecuteDelete
context.Blogs.Where(b => b.Rating < 3).ExecuteDelete();
To vám umožní vyjádřit příkaz SQL DELETE
prostřednictvím běžných operátorů LINQ , podobně jako běžný dotaz LINQ, což způsobí, že se v databázi spustí následující SQL:
DELETE FROM [b]
FROM [Blogs] AS [b]
WHERE [b].[Rating] < 3
To se v databázi provádí velmi efektivně, aniž by se načítala žádná data z databáze nebo zahrnovala sledování změn EF.
ExecuteUpdate Podobně můžete vyjádřit příkaz SQLUPDATE
.
I když hromadně neměníte entity, můžete přesně vědět, které vlastnosti entity chcete změnit. Použití rozhraní API pro sledování změn k provedení změny může být příliš složité, což vyžaduje vytvoření instance entity, sledování prostřednictvím Attach, provádění změn a nakonec volání SaveChanges(). V takových scénářích mohou ExecuteUpdate
a ExecuteDelete
být výrazně jednodušším způsobem vyjádření stejné operace.
Nakonec sledování změn i SaveChanges() samotný ukládá určité režijní náklady za běhu. Pokud píšete vysoce výkonnou aplikaci, můžete se pomocí ExecuteUpdate
a ExecuteDelete
vyhnout oběma těmto komponentám a efektivně vygenerovat požadovaný příkaz.
Mějte však na paměti, že ExecuteUpdate
a ExecuteDelete
také mají určitá omezení:
- Tyto metody se spustí okamžitě a v současné době nelze dávkovat s jinými operacemi. Na druhé straně SaveChanges()může dávkovat více operací dohromady.
- Vzhledem k tomu, že sledování změn není zapojeno, je vaší zodpovědností přesně zjistit, které entity a vlastnosti je potřeba změnit. To může znamenat více manuálního sledování nízkoúrovňového kódu, co je potřeba změnit a co ne.
- Kromě toho, protože sledování změn není zapojeno, tyto metody při zachování změn automaticky nepoužívají řízení souběžnosti . Přesto ale můžete explicitně přidat
Where
klauzuli pro implementaci řízení souběžnosti sami. - V současné době se podporuje pouze aktualizace a odstraňování; vložení musí být provedeno prostřednictvím DbSet<TEntity>.Add a SaveChanges().
Další informace a ukázky kódu naleznete ExecuteUpdate
a ExecuteDelete
.
Shrnutí
Níže najdete několik pokynů pro použití tohoto přístupu. Všimněte si, že tato pravidla nejsou absolutní, ale poskytují užitečná pravidla:
- Pokud předem nevíte, které změny se budou provádět, použijte
SaveChanges
. Automaticky zjistí, které změny je potřeba provést. Ukázkové scénáře:- "Chci načíst blog z databáze a zobrazit formulář, který uživateli umožní ho změnit"
- Pokud potřebujete manipulovat s grafem objektů (tj. více propojených objektů), použijte
SaveChanges
; zjistíte správné pořadí změn a způsob propojení všeho dohromady.- "Chci aktualizovat blog, změnit některé jeho příspěvky a odstranit jiné"
- Pokud chcete změnit potenciálně velký počet entit na základě některého kritéria, použijte
ExecuteUpdate
aExecuteDelete
. Ukázkové scénáře:- "Chci dát všem zaměstnancům zvýšení"
- "Chci odstranit všechny blogy, jejichž jméno začíná X"
- Pokud už víte přesně, které entity chcete upravit a jak je chcete změnit, použijte
ExecuteUpdate
aExecuteDelete
. Ukázkové scénáře:- "Chci odstranit blog, jehož jméno je "Foo".
- Chci změnit název blogu s ID 5 na "Bar"