dotnet / dotnet/efcore

Failed to update nested property in JSON mapped column

Open
#37,411 4 comments 0 reactions 1 assignee Claimed by @AndriySvyryd View on GitHub
area-json area-owned-entities area-sqlite customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Bug description

When updating value inside nested JSON entity I reach unexpected error
```
fail: Microsoft.EntityFrameworkCore.Update[10000]
An exception occurred in the database while saving changes for context type 'AnalysisDbContext'.
System.Diagnostics.UnreachableException: The program executed an instruction that was thought to be unreachable.
at Microsoft.EntityFrameworkCore.Sqlite.Update.Internal.SqliteModificationCommand.ProcessSinglePropertyJsonUpdate(ColumnModificationParameters& parameters)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.g__HandleJson|40_8(List`1 columnModifications, <>c__DisplayClass40_0&)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.GenerateColumnModifications()
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.<>c.b__33_0(ModificationCommand command)
at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.get_ColumnModifications()
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.CreateCommandBatches(IEnumerable`1 commandSet, Boolean moreCommandSets, Boolean assertColumnModification, ParameterNameGenerator parameterNameGenerator)+MoveNext()
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IList`1 entries, IUpdateAdapter updateAdapter)+MoveNext()
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.b__114_0(DbContext _, ValueTuple`2 t)
at Microsoft.EntityFrameworkCore.Storage.NonRetryingExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
System.Diagnostics.UnreachableException: The program executed an instruction that was thought to be unreachable.
at Microsoft.EntityFrameworkCore.Sqlite.Update.Internal.SqliteModificationCommand.ProcessSinglePropertyJsonUpdate(ColumnModificationParameters& parameters)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.g__HandleJson|40_8(List`1 columnModifications, <>c__DisplayClass40_0&)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.GenerateColumnModifications()
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.<>c.b__33_0(ModificationCommand command)
at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.get_ColumnModifications()
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.CreateCommandBatches(IEnumerable`1 commandSet, Boolean moreCommandSets, Boolean assertColumnModification, ParameterNameGenerator parameterNameGenerator)+MoveNext()
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BaUnhandled exception. System.Diagnostics.UnreachableException: The program executed an instruction that was thought to be unreachable.
at Microsoft.EntityFrameworkCore.Sqlite.Update.Internal.SqliteModificationCommand.ProcessSinglePropertyJsonUpdate(ColumnModificationParameters& parameters)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.g__HandleJson|40_8(List`1 columnModifications, <>c__DisplayClass40_0&)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.GenerateColumnModifications()
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.<>c.b__33_0(ModificationCommand command)
at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.get_ColumnModifications()
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.CreateCommandBatches(IEnumerable`1 commandSet, Boolean moreCommandSets, Boolean assertColumnModification, ParameterNameGenerator parameterNameGenerator)+MoveNext()
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IList`1 entries, IUpdateAdapter updateAdapter)+MoveNext()
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.b__114_0(DbContext _, ValueTuple`2 t)
at Microsoft.EntityFrameworkCore.Storage.NonRetryingExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at Program.$(String[] args) in C:\d\scratch\efcorebugjson\Program.cs:line 29
tchCommands(IList`1 entries, IUpdateAdapter updateAdapter)+MoveNext()
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.b__114_0(DbContext _, ValueTuple`2 t)
at Microsoft.EntityFrameworkCore.Storage.NonRetryingExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
```

### Your code

```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddDbContext((services, options) =>
options.UseSqlite("Data Source=test.db"));
var app = builder.Build();
var db = app.Services.GetRequiredService();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
var record = new TheEntity
{
Data = new JsonData
{
NestedData = new NestedClass
{
BrokenValue = true,
},
}
};
db.AnalysisJobs.Add(record);
Console.WriteLine(@record.Data.NestedData.ToString());
db.SaveChanges();
@record = db.AnalysisJobs.First();
var d = @record.Data;
Console.WriteLine(d.ToString());
d.NestedData.BrokenValue = null;
db.SaveChanges();

public class AnalysisDbContext(DbContextOptions options) : DbContext(options)
{
public DbSet AnalysisJobs { get; set; } = null!;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().OwnsOne(
author => author.Data, ownedNavigationBuilder =>
{
ownedNavigationBuilder.ToJson();
ownedNavigationBuilder.OwnsOne(contactDetails => contactDetails.NestedData);

//ownedNavigationBuilder.OwnsOne(contactDetails => contactDetails.HiddenSignals);
});
}

}

public class TheEntity
{
public int Id { get; set; }

public JsonData? Data { get; set; }
}

public class JsonData
{
public NestedClass? NestedData { get; set; } = new();
}

public class NestedClass
{
public bool? BrokenValue { get; set; }
}
```

### Stack traces

```text

```

### Verbose output

```text

```

### EF Core version

10.0.1

### Database provider

_No response_

### Target framework

_No response_

### Operating system

_No response_

### IDE

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.