Five common EF Core performance anti-patterns are examined with code examples, explanations of why they fail at scale, and solutions. The patterns covered are: looping inserts (SaveChanges per row), hand-rolled upserts using FirstOrDefault, load-then-delete with ToList, large-list Contains queries hitting SQL Server's 2,100-parameter limit, and multi-pass table synchronization. EF Core 10 natively solves two of them via AddRange+SaveChanges and ExecuteDelete. The other three — upserts, bulk lookups by large ID lists, and full-table sync — have no clean native answer and are addressed by the commercial Entity Framework Extensions library (BulkMerge, WhereBulkContains, BulkSynchronize). Benchmark data is included for each pattern, along with production gotchas like change tracker staleness, interceptors not firing on bulk operations, and transaction management.

18m read timeFrom woodruff.dev
Post cover image
Table of contents
The Code You Already WroteAnti-Pattern 1: The Loop That Saves Every RowAnti-Pattern 2: The Hand-Rolled UpsertAnti-Pattern 3: Load A Million Rows Just To Delete ThemAnti-Pattern 4: The 2,100 Parameter WallAnti-Pattern 5: Three Passes Where One Would DoConsolidated ViewA Diagnostic Quick ReferenceFootguns That Apply Across All Five PatternsWhere to Go From Here
892 Impressions