EF Core's naive load-modify-save pattern causes severe performance issues at scale, allocating gigabytes of RAM and issuing one SQL statement per entity. EF Core 7+ introduced ExecuteUpdate and ExecuteDelete, which bypass the change tracker and execute a single server-side SQL statement regardless of row count. Benchmarks against 1M rows show these native methods are ~2-4x faster than the naive approach. For server-side INSERT...SELECT (table-to-table copy without loading entities), EF Core 10 still has no native equivalent — Entity Framework Extensions (EFE) fills this gap with InsertFromQuery, which achieves near-constant memory usage and ~22x speedup at 1M rows. Key caveats include stale tracked entities after batch ops, no interceptor/cascade firing, and the need for explicit transactions when mixing batch ops with SaveChanges.
Table of contents
The Code Every Developer Has Written and RegrettedThe Built-In Answer: ExecuteUpdate and ExecuteDeleteThe Missing Piece: There Is No ExecuteInsertEFE’s Batch Operations: UpdateFromQuery, DeleteFromQuery, InsertFromQueryBenchmarks: The Honest NumbersChoosing the Right ToolCaveats That Will Catch You Off-GuardConclusionSort: