BulkUpdate in Entity Framework

BulkUpdate in Entity Framework

In this article, I am going to discuss how to perform BulkUpdate in Entity Framework using Z.EntityFramework.Extensions. Please read our previous article where we discussed how to perform Bulk Insert in Entity Framework.

Note: We are going to work with the same example that we created in our Introduction to Entity Framework Database First Approach article. Please read our introduction to Entity Framework Database First article before proceeding to this article.

Z.EntityFramework.Extensions:

Here, we are going to use Z.EntityFramework.Extensions to perform Bulk Update Operation. So, first, open the NuGet Package Manager window and search for Z.EntityFramework.Extensions package. Select Z.EntityFramework.Extensions and then select the Project and choose the latest version and finally click on the Install button as shown in the below image which will install Z.EntityFramework.Extensions DLL into your project.

BulkUpdate in Entity Framework using Z.EntityFramework.Extensions

Bulk Update in Entity Framework

The BulkUpdate and BulkUpdateAync methods extend our DbContext object which allows us to update a large number of entities into the database. The syntax to use the BulkUpdate extension method as follows:

context.BulkUpdate(studentsList);
context.BulUpdateAsync(studentsList, cancellationToken);

Example: BulkUpdate example using Entity Framework Extensions

In the below example, first, we fetch all the students whose StandardId is 1 and then update the First Name and Last Name and finally update the updated data to the database using the BulkUpdate method.

using System;
using System.Linq;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("BulkUpdate Method Started");
            BulkUpdate(1);
            Console.WriteLine("BulkUpdate Method Completed");
            GetStudents(1);
            Console.Read();
        }

        public static void BulkUpdate(int StandardId)
        {
            using (var context = new EF_Demo_DBEntities())
            {
                //Get all the students
                var studentsList = context.Students.Where(std => std.StandardId == StandardId);

                //Update the Firstname and LastName
                foreach (var std in studentsList)
                {
                    std.FirstName += " Changed";
                    std.LastName += " Changed";
                }

                // Easy to use
                context.BulkUpdate(studentsList);
            }
        }

        public static void GetStudents(int StandardId)
        {
            using (var context = new EF_Demo_DBEntities())
            {
                var studentsList = context.Students.Where(std => std.StandardId == StandardId);
                foreach (var std in studentsList)
                {
                    Console.WriteLine($"FirstName : {std.FirstName}, LastName : {std.LastName}, StandardId : {std.StandardId}");
                }
            }
        }
    }
}

Output:

BulkUpdate example using Entity Framework Extensions

Performance Comparison Between SaveChanges and BulkUpdate:

Let see the performance benchmark between the saveChanges and BulkUpdate extension method. In the below example, first, we are inserting 1000 students into the student table and then we are going updating the first name and last name of all the students using both the approach. Here, will also print the time taken to complete the execution of both approaches.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            //First Add 1000 Students
            AddStudents();

            var clockSaveChanges = new Stopwatch();
            var clockBulkUpdate = new Stopwatch();

            using (var context = new EF_Demo_DBEntities())
            {
                // SaveChanges
                var studentList = context.Students.ToList();
                foreach (var std in studentList)
                {
                    std.FirstName += "_Update";
                    std.LastName += "_Update";
                }

                clockSaveChanges.Start();
                context.SaveChanges();
                clockSaveChanges.Stop();

                Console.WriteLine($"SaveChanges (EF), Entities : {studentList.Count}, Performance : {clockSaveChanges.ElapsedMilliseconds} ms");
            }

            using (var context = new EF_Demo_DBEntities())
            {
                // BulkInsert
                var studentList = context.Students.ToList();
                foreach (var std in studentList)
                {
                    std.FirstName += "_Changed";
                    std.LastName += "_Changed";
                }

                clockBulkUpdate.Start();
                context.BulkUpdate(studentList);

                clockBulkUpdate.Stop();
                Console.WriteLine($"BulkInsert (EF Extensions), Entities : {studentList.Count}, Performance : {clockBulkUpdate.ElapsedMilliseconds} ms");
            }

            Console.Read();
        }

        public static void AddStudents()
        {
            //Add 1000 Students for Performance Testing
            var stduentsList = GenerateStudents(1000);

            // BulkInsert
            using (var context = new EF_Demo_DBEntities())
            {
                context.BulkInsert(stduentsList, options => options.AutoMapOutputDirection = false);
            }
        }

        public static List<Student> GenerateStudents(int count)
        {
            var Studentlist = new List<Student>();

            for (int i = 0; i < count; i++)
            {
                Studentlist.Add(new Student() { FirstName = "FirstName_" + i, LastName = "LastName_" + i, StandardId = 1 });
            }

            return Studentlist;
        }
    }
}

Output: You can see in the below output, the SaveChanges method took 954 ms time to update 1005 rows into the database while the BulkUpdate extension method took only 147 ms to update the same 1005 records into the database.

Performance Comparison Between SaveChanges and BulkUpdate

Note: A lot of factors need to be considered for affecting the benchmark time such as index, column type, latency, throttling, etc.

Why BulkUpdate is faster than SaveChanges?

In real-time applications, it is a common task to update 1000 entities. The SaveChanges method makes it quite impossible to handle this kind of situation due to the number of database round-trips required. The SaveChanges perform one database round-trip for every entity to update. So, if you need to update 10,000 entities, 10,000 database round-trips will be performed which is make it slow. If you are performing the update operation using any API, then it might be possible for the client who consumes your API gets a time-out error as the update operation going to take a huge amount of time.

The BulkUpdate in counterpart requires the minimum database round-trips possible. For example, under the hood for SQL Server, a SqlBulkCopy is performed first in a temporary table, then an UPDATE from the temporary table to the destination table is performed which is the fastest way available.

Advantages of BulkUpdate Extension Method in Entity Framework:
  1. Easy to use, simply calling the BulkUpdate Method
  2. Flexible as it also provides different options.
  3. Increase performance due to reducing database round-trips
  4. Increase application responsiveness
  5. Due to reduction in database round-trips, it also reduces the load on the database
Scenarios to use BulkUpdate

The BulkUpdate Extension method is not only fast but also so flexible that lets us handle various scenarios in Entity Framework. Some of them are as follows:

  1. Update and include/exclude properties
  2. Update with custom key
  3. Update with related child entities (Include Graph)
  4. Update with future action

In the next article, I am going to discuss the BulkDelete Extension method in Entity Framework with Examples. Here, in this article, I try to explain the BulkUpdate Extension method in Entity Framework with examples. I hope you enjoy this BulkInsert Extension method in the Entity Framework article.

Leave a Reply

Your email address will not be published. Required fields are marked *