How To Use The New Bulk Update Feature In EF Core 7
Tags: efcore, aspnetcore, dotnet, csharp
Published: 2023-09-16 10:50:08

---
title: How To Use The New Bulk Update Feature In EF Core 7
published: true
date: 2022-11-26 00:00:00 UTC
tags: efcore,aspnetcore,dotnet,csharp
canonical_url: https://www.milanjovanovic.tech/blog/how-to-use-the-new-bulk-update-feature-in-ef-core-7
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/862u0mnem3ueggp8pzp0.png
---
In this week's newsletter, we're going to explore the new`ExecuteUpdate` and `ExecuteDelete` methods that were released with **EF7**.

`ExecuteUpdate` allows us to write a query and run a bulk update operation on the entities matching that query.

Similarly, `ExecuteDelete` allows us to write a query and delete the entities matching that query.

We can significantly improve performance using the new methods in some scenarios, and I'm going to show you what those scenarios are.

## Updating And Deleting Entities Before EF Core 7

If you want to update a collection of entities before **EF7** , you need to load the entities into memory using the `DatabaseContext`.

The **EF ChangeTracker** will then track any changes made to these entities. When you are ready to commit the changes to the database, you simply call the `SaveChanges` method.

Here's an example where we load a few notifications, and we want to snooze them so they aren't sent:

```csharp
var notifications = dbContext
    .Notifications
    .Where(n => !n.Snoozed)
    .ToList();

foreach(var notification in notifications)
{
    notification.Snoozed = true;
}

dbContext.SaveChanges();
```

**EF7** will generate the following **SQL** statement to update the records in the database:

```SQL
UPDATE [Notifications] n
SET n.[Snoozed] = TRUE
WHERE n.[Id] = @notificationId_1;

...

UPDATE [Notifications] n
SET n.[Snoozed] = TRUE
WHERE n.[Id] = @notificationId_N;
```

Notice that for every notification we end up with one **SQL UPDATE** statement. This won't scale well as the number of notifications increases.

## Updating Entities With ExecuteUpdate

With **EF7**, we now have access to the new `ExecuteUdpate` method. It also has an asynchronous version - `ExecuteUpdateAsync`.

How do you use it?

You need to write a query that will select the records you want to update, and then call the `ExecuteUpdate` method on the resulting `IQueryable`.

Let's rewrite the previous example using the new approach:

```csharp
dbContext
    .Notifications
    .Where(n => !n.Snoozed)
    .ExecuteUpdate(s => s.SetProperty(
        n => n.Snoozed,
        n => true));
```

In the call to `ExecuteUpdate` we call the `SetProperty` method to specify which properties we want to update, and what values we want to set. The `SetProperty` method can be called multiple times, if you need to update more than one property.

In this case, **EF7** will generate the following **SQL** query:

```SQL
UPDATE n
SET n.[Snoozed] = TRUE
FROM [Notifications] AS n
WHERE n.[Snoozed] = FALSE;
```

Notice that this time we only have one **SQL** query being sent to the database. This is a major performance improvement. It can be as much as 10x faster than the old version, from my testing.

## Deleting Entities With ExecuteDelete

Let's also see how we can do bulk deletes using the `ExecuteDelete` and `ExecuteDeleteAsync` methods.

Again, you have to write a query that will select the records you want to delete, and then call the `ExecuteDelete` method on the resulting `IQueryable`.

If you want to delete all snoozed notifications:

```csharp
dbContext
    .Notifications
    .Where(n => n.Snoozed)
    .ExecuteDelete();
```

And **EF7** will generate the following **SQL** query:

```SQL
DELETE FROM n
FROM [Notifications] AS n
WHERE n.[Snoozed] = TRUE;
```

I think this will be incredibly useful when you want to delete records in the database based on a specific condition.

## Transactions, Change Tracking And Query Filters With Bulk Methods

You need to be aware how transactions and change tracking work with the new bulk methods. `ExecuteUpdate` and `ExecuteDelete` will immediately go to database, and run the **SQL** query.

**What does this mean for transactions?**

If you want to run a bulk method together with other updates applied with `SaveChanges`, by default they won't run in the same transaction. You need to open an explicit **transaction** using the `DatabaseContext` to keep everything consistent.

**What does this mean for change tracking?**

`ExecuteUpdate` and `ExecuteDelete` run directly on the database, without loading any entities into memory. **EF7** will not track these entities in the `ChangeTracker`.

If you have any database interceptors defined, they won't execute after calling one of the bulk update methods. This also means that if you override `SaveChanges`to add custom behavior, it won't be called.

**Do Query Filters still work?**

Yes, **query filters** will be **correctly applied** when calling `ExecuteUpdate` or `ExecuteDelete`.

## When Should You Use The New Bulk Methods?

I think this is an excellent new addition to **EF7**, and it solves a real problem when you need to run a typical **UPDATE** or **DELETE** query with a **WHERE** statement applied.

Previously, you had to write raw **SQL** and execute it using something like **Dapper**.

I will likely use this approach when it applies to my projects.

* * *
**P.S. Whenever you're ready, there are 2 ways I can help you:**

1. [**Pragmatic Clean Architecture:**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting) This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. [**Join 950+ students here.**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting)

2. [**Patreon Community:**](https://www.patreon.com/milanjovanovic) Think like a senior software engineer with **access to the source code** I use in my YouTube videos and **exclusive discounts** for my courses. [**Join 820+ engineers here.**](https://www.patreon.com/milanjovanovic)