HomeNikola Knezevic

In this article

Banner

Execute Update with JSON in EF Core

19 Feb 2026
5 min

Special Thanks to Our Sponsors:

Sponsor Logo

EF Core is too slow? Discover how you can easily insert 14x faster (reducing saving time by 94%).

Boost your performance with our method within EF Core: Bulk Insert, update, delete and merge.

Thousands of satisfied customers have trusted our library since 2014.

👉 Learn more

Sponsor Newsletter

With the new JSON data type introduced in SQL Server, the database finally provides native support for efficient and type-safe JSON storage and querying.

This change also unlocked new possibilities for the ExecuteUpdate method in EF Core, which can now work directly with JSON columns.

Execute update

ExecuteUpdate was introduced in EF Core to simplify bulk updates at the database level. It offers significantly better performance compared to the traditional approach of loading entities, modifying them, and calling SaveChanges.

csharp
await _dbContext.Products
    .ExecuteUpdateAsync(set => set
        .SetProperty(p =>
            p.Price, p => p.Price * 1.02m));

Over time, it gained support for complex types, and now it also works with JSON columns.

NOTE: ExecuteUpdate bypasses the change tracker.

This means you do not need to call SaveChanges. The update is executed directly in the database.

If you want it to be part of the same unit of work as other changes, you need to wrap it in a transaction:

csharp
await using var connection = new NpgsqlConnection(ConnectionString);
await connection.OpenAsync();

var transaction = await connection.BeginTransactionAsync();

await _dbContext.Products
    .ExecuteUpdateAsync(set => set
        .SetProperty(p =>
            p.Price, p => p.Price * 1.02m));

await transaction.CommitAsync();

Getting started

If you want to learn more about JSON support in EF Core, check out my previous blog post: JSON Type Support in EF Core 10.

For this example, we will use a Blog entity that contains a complex type stored as JSON:

csharp
public class Blog
{
    public int Id { get; set; }
    public BlogDetails Details { get; set; }
}

public class BlogDetails
{
    public int Views { get; set; }
    public string[] Tags { get; set; }
    public List<Author> Authors { get; set; }
}

public class Author
{
    public string Name { get; set; }
    public string Email { get; set; }
}

In EF Core, we configure Details as a JSON column:

csharp
public class BlogConfiguration : IEntityTypeConfiguration<Blog>
{
    public void Configure(EntityTypeBuilder<Blog> builder)
    {
        builder.ToTable(TableNames.Blogs);

        builder.HasKey(b => b.Id);

        builder.ComplexProperty(b => b.Details, bd => bd.ToJson());
    }
}

Updating Property

Now we can easily update properties inside the JSON document without loading entities into memory:

csharp
app.MapPut("blogs/views", async (ApplicationDbContext dbContext) =>
{
    await dbContext.Blogs.ExecuteUpdateAsync(s =>
        s.SetProperty(b => b.Details.Views, b => b.Details.Views + 1));

    return Results.NoContent();
});

Updating a Collection

The same concept applies to collections:

csharp
app.MapPut("blogs/tags", async (ApplicationDbContext dbContext) =>
{
    await dbContext.Blogs.ExecuteUpdateAsync(s =>
        s.SetProperty(b => b.Details.Tags, b => new string[] { "1", "2", "3" }));

    return Results.NoContent();
});

app.MapPut("blogs/authors", async (ApplicationDbContext dbContext) =>
{
    await dbContext.Blogs.ExecuteUpdateAsync(s =>
        s.SetProperty(
            b => b.Details.Authors,
            b => new List<Author>
            {
                new WebApi.Entities.Author()
                {
                    Name = "Nikola",

                    Email = "nikola.knezevic@nikolatech.net"
                }
            }));

    return Results.NoContent();
});

However, working with collections has its limitations, you cannot perform arbitrary operations inside JSON collections.

Even though SQL Server supports JSON and EF Core 10 can update JSON columns in bulk, ExecuteUpdate still has strict translation rules.

It can only generate a single SQL SET expression, which means it cannot iterate over or mutate individual elements of a list.

Because of this, LINQ operations like Select, Add, Remove cannot be translated and will fail when used inside ExecuteUpdate.

Conclusion

The new JSON data type in SQL Server, combined with EF Core’s ExecuteUpdate, brings a powerful and efficient way to perform bulk updates.

You can now update properties inside JSON documents or even replace entire collections with a single database command.

However, it is important to understand the limitations. ExecuteUpdate works with strict SQL translation rules. You can replace them, but you cannot modify individual elements using LINQ operations.

If you want to check out examples I created, you can find the source code here:

Source Code

I hope you enjoyed it, subscribe and get a notification when a new blog is up!

Subscribe

Stay tuned for valuable insights every Thursday morning.