Ukládání dat
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 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 = context.Blogs.Single(b => b.Url == "http://example.com");
blog.Url = "http://example.com/blog";
context.SaveChanges();
}
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í sledují, což znamená, že EF sleduje načtené entity v interním sledování změn.
- Načtená instance entity se manipuluje obvyklým způsobem přiřazením vlastnosti .NET. Ef není součástí tohoto kroku.
- DbContext.SaveChanges() Nakonec se zavolá. 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 popsaná typická operace aktualizace pro existující data, ale podobné principy se uchovávají 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")
Poznámka:
Tato funkce byla představena v EF Core 7.0.
Sledování změn a SaveChanges() je výkonným způsobem, jak uložit změny, mají určité nevýhody.
Nejprve je nutné, abyste se dotazování a sledování všech entit, SaveChanges() které budete upravovat nebo odstraňovat, upravili nebo odstranili. Pokud potřebujete, řekněme, 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 a 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 může ExecuteDelete
být výrazně jednodušší způsob vyjádření ExecuteUpdate
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 a ExecuteUpdate
ExecuteDelete
můžete se 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ě není možné provádět dávky 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 ruční sledování kódu nízké úrovně, které 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
.
Souhrn
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
ho. Automaticky zjistí, které změny je potřeba použít. 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 panel"