Efektivní aktualizace
Dávkování
EF Core pomáhá minimalizovat zaokrouhlování tím, že automaticky seskupí všechny aktualizace v rámci jednoho kruhového převodu. Vezměte v úvahu následující skutečnosti:
var blog = context.Blogs.Single(b => b.Url == "http://someblog.microsoft.com");
blog.Url = "http://someotherblog.microsoft.com";
context.Add(new Blog { Url = "http://newblog1.microsoft.com" });
context.Add(new Blog { Url = "http://newblog2.microsoft.com" });
context.SaveChanges();
Výše uvedené načte blog z databáze, změní jeho adresu URL a pak přidá dva nové blogy; k použití tohoto příkazu se do databáze odešlou dva příkazy SQL INSERT a jeden příkaz UPDATE. Místo toho, aby se tyto změny posílaly jednotlivě, protože se přidají instance blogu, EF Core tyto změny interně sleduje a při zavolání je spustí v jednom kruhovém rozjezdu SaveChanges .
Počet příkazů, které ef batches v jednom zaokrouhlování závisí na používaném poskytovateli databáze. Například analýza výkonu ukázala, že dávkování je obecně méně efektivní pro SQL Server, pokud se týká méně než 4 příkazů. Podobně výhody dávkového snížení výkonu po přibližně 40 příkazech pro SQL Server, takže EF Core ve výchozím nastavení spustí až 42 příkazů v jedné dávce a provede další příkazy v samostatných zaokrouhlování.
Uživatelé také můžou tyto prahové hodnoty upravit, aby dosáhli potenciálně vyššího výkonu, ale před úpravou těchto hodnot pečlivě proveďte srovnávací testy:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True",
o => o
.MinBatchSize(1)
.MaxBatchSize(100));
}
Použití ExecuteUpdate a ExecuteDelete, pokud jsou relevantní
Předpokládejme, že chcete všem svým zaměstnancům dát zvýšení. Typická implementace pro tuto implementaci v EF Core by vypadala takto:
foreach (var employee in context.Employees)
{
employee.Salary += 1000;
}
context.SaveChanges();
I když je to dokonale platný kód, pojďme analyzovat, co dělá z hlediska výkonu:
- Provede se zaokrouhlit databáze, aby se načetli všichni relevantní zaměstnanci; Všimněte si, že to klientovi přináší všechna data řádků zaměstnanců, i když bude potřeba jenom mzda.
- Sledování změn EF Core vytváří snímky při načítání entit a pak tyto snímky porovnává s instancemi a zjistí, které vlastnosti se změnily.
- Za účelem uložení všech změn se obvykle provádí druhé zaokrouhlení databáze (upozorňujeme, že někteří poskytovatelé databáze změny rozdělí na násobky zaokrouhlit). I když je toto dávkové chování mnohem lepší než provádění přeokrouhlování pro každou aktualizaci, EF Core stále odesílá příkaz UPDATE pro každého zaměstnance a databáze musí každý příkaz spouštět samostatně.
Počínaje EF Core 7.0 můžete pomocí ExecuteUpdate
ExecuteDelete
metod provádět totéž mnohem efektivněji:
context.Employees.ExecuteUpdate(s => s.SetProperty(e => e.Salary, e => e.Salary + 1000));
Tím se do databáze odešle následující příkaz SQL:
UPDATE [Employees] SET [Salary] = [Salary] + 1000;
Tím UPDATE
se provede celá operace v jednom kruhovém provozu, aniž by se do databáze načítala nebo neodesílala žádná skutečná data, a bez použití zařízení EF pro sledování změn, což představuje další režii. Další informace najdete v tématech ExecuteUpdate
a ExecuteDelete
.
Pokud používáte starší verzi EF Core, která ještě nepodporuje ExecuteUpdate
a ExecuteDelete
nebo chcete spustit složitý příkaz SQL, který tyto metody nepodporuje, můžete k provedení operace použít dotaz SQL:
context.Database.ExecuteSql($"UPDATE [Employees] SET [Salary] = [Salary] + 1000");
Další informace o rozdílech mezi SaveChanges
daty a ExecuteUpdate
ExecuteDelete
/najdete na stránce Přehled při ukládání dat.