dotnet/efcore · error · InvalidOperationException

JsonPartialExecuteUpdateNotSupportedByProvider

JsonPartialExecuteUpdateNotSupportedByProvider

Error message

The provider in use does not support partial updates with ExecuteUpdate within JSON columns.

What it means

The base RelationalQueryableMethodTranslatingExpressionVisitor.GenerateJsonPartialUpdateSetter (line 919-923) is a provider extension point that, by default, just throws JsonPartialExecuteUpdateNotSupportedByProvider. A provider (e.g. SQL Server, PostgreSQL) overrides it to emit its JSON modification syntax (JSON_MODIFY, jsonb_set). If the provider in use does not override it, any partial JSON ExecuteUpdate (updating a scalar inside a JSON column) fails.

Source

Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:923

    /// <summary>
    ///     Provider extension point for implementing partial updates within JSON columns.
    /// </summary>
    /// <param name="target">
    ///     An expression representing the target to be updated; can be either <see cref="JsonScalarExpression" />
    ///     (when a scalar property is being updated within the JSON column), or a <see cref="JsonQueryExpression" />
    ///     (when an object or collection is being updated).
    /// </param>
    /// <param name="value">The JSON value to be set, ready for use as-is in <see cref="QuerySqlGenerator" />.</param>
    /// <param name="existingSetterValue">
    ///     If a setter was previously created for this JSON column, it's value is passed here (this happens when e.g.
    ///     multiple properties are updated in the same JSON column). Implementations can compose the new setter into
    ///     the existing one (and return <see langword="null" />), or return a new one.
    /// </param>
    protected virtual SqlExpression? GenerateJsonPartialUpdateSetter(
        Expression target,
        SqlExpression value,
        ref SqlExpression? existingSetterValue)
        => throw new InvalidOperationException(RelationalStrings.JsonPartialExecuteUpdateNotSupportedByProvider);

    private static T? ParameterValueExtractor<T>(
        QueryContext context,
        string baseParameterName,
        List<IComplexProperty>? complexPropertyChain,
        IProperty property)
    {
        var baseValue = context.Parameters[baseParameterName];

        if (complexPropertyChain is not null)
        {
            foreach (var complexProperty in complexPropertyChain)
            {
                if (baseValue is null)
                {
                    break;
                }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Switch to a provider that implements JSON partial updates (SQL Server, PostgreSQL Npgsql).
  2. Update the entire JSON column as a whole (SetProperty on the full complex value) instead of a partial scalar path, if the provider supports whole-column updates.
  3. Map the data as flattened columns instead of JSON so partial updates become plain column updates.
  4. Perform the partial JSON update via raw SQL using the database's JSON functions.

Example fix

// before (SQLite does not implement partial JSON ExecuteUpdate)
db.Contacts.ExecuteUpdate(s => s.SetProperty(
    c => c.Address.City, "NYC")); // Address is a JSON complex type

// after (map as flattened complex columns instead of JSON)
modelBuilder.Entity<Contact>().ComplexProperty(c => c.Address);
db.Contacts.ExecuteUpdate(s => s.SetProperty(
    c => c.Address.City, "NYC"));
Defensive patterns

Strategy: validation

Validate before calling

// Detect provider support before relying on partial JSON ExecuteUpdate.
var supportsJsonPartial = db.Database.ProviderName switch
{
    "Microsoft.EntityFrameworkCore.SqlServer" => true,
    "Npgsql.EntityFrameworkCore.PostgreSQL" => true,
    _ => false
};
if (!supportsJsonPartial) throw new InvalidOperationException("Provider lacks JSON partial ExecuteUpdate; flatten columns or use raw SQL.");

Try / catch

try { await q.ExecuteUpdateAsync(s => s.SetProperty(e => e.Json.X, v)); }
catch (InvalidOperationException ex) when (ex.Message.Contains("partial updates"))
{ /* switch provider, flatten to columns, or update the whole JSON column via raw SQL */ }

Prevention

When it happens

Trigger: Using a database provider that has not implemented JSON partial updates (e.g. SQLite, or a third-party provider) and calling ExecuteUpdate that targets a scalar property inside a JSON column, triggering GenerateJsonPartialUpdateSetter.

Common situations: Switching from SQL Server to SQLite (which lacks the override) while keeping JSON-mapped complex types; using a community provider with partial JSON support; provider version that predates the JSON ExecuteUpdate work.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/322b8775b1f80ce0. Report an issue: GitHub.