Explain Codes LogoExplain Codes Logo

Update multiple rows in Entity Framework from a list of ids

sql
bulk-operations
entity-framework
database-performance
Alex KataevbyAlex Kataev·Dec 29, 2024
TLDR

Set your eyes on this dazzling bulk update for multiple rows utilizing a filter in a single move:

using (var context = new YourContext()) { var idsToUpdate = new List<int> { /* Insert your ID numbers here. Don't be shy! */ }; var itemsToUpdate = context.YourEntity.Where(entity => idsToUpdate.Contains(entity.Id)); foreach (var item in itemsToUpdate) { item.PropertyToUpdate = "NewValue"; // Give it a new sparkle of life. // Feel free to design the rest of the house (update other properties) } context.SaveChanges(); // Save those shiny new updates. It's locked and loaded! }

For the uninitiated in muttered chants, replace YourContext, YourEntity, and PropertyToUpdate with your respective names (don't worry, no identity theft is going on here). Entity Framework tracks all your changes and wraps them up with SaveChanges(). Sweet and simple!

Efficient update patterns (or dancing with Entity Framework)

For the "early-adapters": EF Core 7 clever touches

If you're using EF Core 7, allow ExecuteUpdate to optimize bulk operations. Basically, it's like eating your cake without getting fat:

context.YourEntity.Where(e => idsToUpdate.Contains(e.Id)) .ExecuteUpdate(b => b.SetProperty(e => e.PropertyToUpdate, "NewValue")); // This does the magic trick!

Doing it this way keeps your entities light-weight (no memory overload), boosting performance. It's the life-hack you've been seeking.

Heavy operation? No thanks, said EF Core

To avoid performance nose-dives and clamp down the need for external libraries, employ context.Database.ExecuteSqlRaw, the strong-arm of EF Core for batch updates:

var sql = "UPDATE YourEntity SET PropertyToUpdate = {0} WHERE Id IN ({1})"; context.Database.ExecuteSqlRaw(sql, newValue, string.Join(", ", idsToUpdate)); // SQL steroids for your IDs

Prioritize SQL injection safety with parameterized queries. Use IQueryable.ToQueryString and you'll have the generated SQL for review. Call it SQL auditing.

Supercharging with async/await (the Flash would be proud)

Scalability is nothing but a game of async/await applied correctly. Run your database operations inside this ecosystem to make your apps more responsive and potent at handling I/O-related tasks:

using (var context = new YourContext()) { var idsToUpdate = // your IDs. Yes, those ones. var itemsToUpdate = await context.YourEntity .Where(entity => idsToUpdate.Contains(entity.Id)) .ToListAsync(); // Gather friends for a party! itemsToUpdate.ForEach(item => item.PropertyToUpdate = "NewValue"); // More updates, more fun. await context.SaveChangesAsync(); // Secure the party captures. }

Handling massive ID traffic

Working with Godzilla-sized lists of IDs could potentially slow down performance. Keep an eye out for data jams, and consider breaking it down into bite-sized batches:

const int batchSize = 100; var batches = idsToUpdate.Batch(batchSize); foreach (var batch in batches) { // Call in your operations as shown in earlier examples with each batch }

The GitHub crystal ball

Frequent GitHub to stay updated. Issue #795, for instance, gives a sneak peek into the future of bulk update capabilities in Entity Framework Core. So, keep those crystal balls polished.

Riding third-party horses

Frameworks such as Zack.EFCore.Batch do the heavy lifting for batch updates, while keeping database round trips at a minimum:

// Via NuGet > Install-Package Zack.EFCore.Batch context.UpdateRange(idsToUpdate.Select(id => new YourEntity { Id = id, PropertyToUpdate = "NewValue" })); context.SaveChanges(); // secure the goods

Zack's GitHub repo and Reddit guide will lead you safely through the wilds, so keep them handy.