Megosztás a következőn keresztül:


Hatékony frissítés

Csoportosítás

Az EF Core segít minimalizálni a visszafordulásokat azáltal, hogy az összes frissítést automatikusan egyetlen körutazásba csoportosítja. Vegye figyelembe a következőket:

var blog = await context.Blogs.SingleAsync(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" });
await context.SaveChangesAsync();

A fentiek betöltenek egy blogot az adatbázisból, módosítják annak URL-címét, majd hozzáadnak két új blogot; Ennek alkalmazásához a rendszer két SQL INSERT-utasítást és egy UPDATE utasítást küld az adatbázisnak. Ahelyett, hogy egyenként küldené el őket, a blogpéldányok hozzáadásakor az EF Core belsőleg követi nyomon ezeket a módosításokat, és egyetlen körúton hajtja végre őket SaveChanges meghívásakor.

Az, hogy az EF kötegek egy kódkörúton belül hány utasítást tartalmaznak, a használt adatbázis-szolgáltatótól függ. A teljesítmény-elemzés például azt mutatta, hogy a kötegelés általában kevésbé hatékony az SQL Server esetében, ha kevesebb mint 4 utasításról van szó. Hasonlóképpen, a kötegelés előnyei az SQL Server esetében körülbelül 40 utasítás után csökkennek, így az EF Core alapértelmezés szerint csak 42 utasítást hajt végre egyetlen kötegben, és további utasításokat hajt végre külön kerekítésekben.

A felhasználók ezeket a küszöbértékeket is módosíthatják, hogy potenciálisan nagyobb teljesítményt érjenek el – de a módosítás előtt gondosan mérjék fel a teljesítményt:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer(
        @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True",
        o => o
            .MinBatchSize(1)
            .MaxBatchSize(100));
}

Az ExecuteUpdate és az ExecuteDelete használata, ha releváns

Tegyük fel, hogy minden alkalmazottjának emelést szeretne adni. Ehhez az EF Core-ban egy tipikus implementáció a következőhöz hasonlóan nézne ki:

foreach (var employee in context.Employees)
{
    employee.Salary += 1000;
}
await context.SaveChangesAsync();

Bár ez tökéletesen érvényes kód, elemezzük a teljesítmény szempontjából, hogy mit csinál:

  • Egy adatbázis-lekérdezést hajtunk végre az összes releváns alkalmazott betöltéséhez. Vegye figyelembe, hogy ez az összes alkalmazotti rekordadatot a felhasználó gépére hozza el, még akkor is, ha csak a fizetésre lesz szükség.
  • Az EF Core változáskövetése pillanatképeket hoz létre az entitások betöltésekor, majd összehasonlítja ezeket a pillanatképeket a példányokkal, hogy megtudja, mely tulajdonságok változtak.
  • Az összes módosítás mentéséhez általában egy második adatbázis-kerekítést hajtanak végre (vegye figyelembe, hogy egyes adatbázis-szolgáltatók többszörös kerekítésekre osztják a módosításokat). Bár ez a kötegelési viselkedés sokkal jobb, mint az egyes frissítésekhez szükséges minden egyes kapcsolódási kör végrehajtása, az EF Core továbbra is küld egy UPDATE utasítást minden egyes alkalmazotthoz, és az adatbázis külön hajtja végre az egyes utasításokat.

Az EF Core 7.0-tól kezdve a ExecuteUpdateAsync és ExecuteDeleteAsync metódusokkal sokkal hatékonyabban végezheti el ugyanezt:

await context.Employees.ExecuteUpdateAsync(s => s.SetProperty(e => e.Salary, e => e.Salary + 1000));

Ez a következő SQL-utasítást küldi az adatbázisnak:

UPDATE [Employees] SET [Salary] = [Salary] + 1000;

Ez a UPDATE a teljes műveletet egyetlen fordulóban hajtja végre anélkül, hogy tényleges adatokat töltene be vagy küldhet az adatbázisba, és ne használhassa az EF változáskövetési gépét, ami további többletterhelést ró. További információ: ExecuteUpdate és ExecuteDelete.

Ha az EF Core egy régebbi verzióját használja, amely még nem támogatja ExecuteUpdate és ExecuteDelete, vagy olyan összetett SQL-utasítást szeretne végrehajtani, amelyet ezek a metódusok nem támogatnak, akkor is használhat SQL-lekérdezést a művelet végrehajtásához:

context.Database.ExecuteSql($"UPDATE [Employees] SET [Salary] = [Salary] + 1000");

A SaveChanges és a ExecuteUpdate/ExecuteDeleteközötti különbségekről további információt az adatok mentése témakörű Áttekintési oldalon talál.