Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF - Update multiple rows in database without using foreach loop

My test code:

using (var db = new MyDbContext())
{
  string fromUser = ""; //sender
  string toUser = ""; //receiver

  var messages = db.Message.Where(x => x.FromUser == fromUser && x.ToUser == toUser)
                 .ToList();

  foreach (var message in messages)
  {
    message.IsRead = true;
    db.SaveChanges();
  }
}

My question: is there another way to update database without using foreach loop in that case?

p/s: I'd been reference these questions but all of them didn't solve my problem:

  • Update multiple rows in datatable without loop

  • updating multiple records in database with linq to sql without loop, is it possible?

  • Update multiple rows without looping

like image 831
Tân Avatar asked Dec 05 '15 16:12

Tân


People also ask

Is it possible to perform bulk updates in EF?

This performs the entire operation in a single roundtrip, without loading or sending any actual data to the database, and without making use of EF's change tracking machinery, which imposes an additional overhead. Unfortunately, EF doesn't currently provide APIs for performing bulk updates.

How many statements should an EF batch contain in a roundtrip?

The number of statements that EF batches in a single roundtrip depends on the database provider being used. For example, performance analysis has shown batching to be generally less efficient for SQL Server when less than 4 statements are involved.

What is a second database roundtrip in EF Core?

A second database roundtrip is performed to save all the changes. While all changes are done in a single roundtrip thanks to batching, EF Core still sends an UPDATE statement per employee, which must be executed by the database. Relational databases also support bulk updates, so the above could be rewritten as the following single SQL statement:

Is it possible to update multiple records in database with LINQ?

updating multiple records in database with linq to sql without loop, is it possible? You don't need to SaveChanges () on each iteration. That will hit the database multiple times.


2 Answers

Just to update Steve's answer, in newer EF (current EF Core 3.1.3) you can do it all as one statement.

await db.Message.Where(m => m.FromUser == fromUser && m.ToUser == toUser).ForEachAsync(m => m.IsRead = true);
await db.SaveChangesAsync().ConfigureAwait(false);
like image 81
Scott R. Frost Avatar answered Oct 04 '22 11:10

Scott R. Frost


You don't need to SaveChanges() on each iteration. That will hit the database multiple times. Try:

using (var db = new MyDbContext())
{
  string fromUser = ""; //sender
  string toUser = ""; //receiver
  var messages = db.Message.Where(x => x.FromUser == fromUser && x.ToUser == toUser)
                 .ToList();
  messages.ForEach(m => m.IsRead = true);
  db.SaveChanges();
}
like image 25
Steve Greene Avatar answered Oct 04 '22 13:10

Steve Greene