Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving related data in JSONB not performed automatically #3312

Closed
armanossiloko opened this issue Oct 12, 2024 · 2 comments
Closed

Saving related data in JSONB not performed automatically #3312

armanossiloko opened this issue Oct 12, 2024 · 2 comments

Comments

@armanossiloko
Copy link

armanossiloko commented Oct 12, 2024

I noticed that if I have related data which is stored as JSONB, updating the related data through another entity will not performed unless I set context.Entry(entity).Property(u => u.Metadata).IsModified = true;. As an example, consider the scenario where I have a Person that has multiple addresses, like this:

public class Person
{
    public int Id { get; set; }
    public required string Name { get; set; }
    public List<Address> Addresses { get; set; } = [];
}
public class Address
{
    public int Id { get; set; }
    public string? StreetName { get; set; }
    public int PersonId { get; set; }
    public virtual Person? Person { get; set; }
    public Metadata Metadata { get; set; }
}
public class Metadata
{
    public int HouseNumber { get; set; }
    public string? Door { get; set; }
}

With a DbContext setup such as this:

public class MyDbContext(DbContextOptions<MyDbContext> options) : DbContext(options)
{
    public DbSet<Person> People { get; set; }
    public DbSet<Address> Addresses { get; set; }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        builder.Entity<Address>()
            .Property(e => e.Metadata)
            .HasColumnType("jsonb");
    }
}

Creating a Person would work just fine. All data would be inserted and nothing would be incorrect. However, in the /update endpoint, if I try to update an Address.Metadata through a Person, the Metadata properties won't be updated in the database unless I explicitly (for each address) declare that the Metadata has changes: context.Entry(address).Property(u => u.Metadata).IsModified = true;. Why is this the case

app.MapPost("/add", (MyDbContext context) =>
{
    Person person = new()
    { 
        Name = "Person 1", 
        Addresses = new()
        {
            new()
            {
                PersonId = 1,
                Metadata = new() { HouseNumber = 30, Door = "N/A" },
            }
        }
    };
    context.People.Add(person);
    context.SaveChanges();
    return Results.Ok();
});
app.MapPost("/update", (MyDbContext context) =>
{
    var person = context.People.Include(x => x.Addresses).FirstOrDefault(x => x.Id == 1);
    foreach (var address in person.Addresses)
    {
        address.Metadata.HouseNumber = 36;
        address.Metadata.Door = "John Doe";

        //context.Entry(address).Property(u => u.Metadata).IsModified = true;
        // Without the line above, the Metadata will remain as HouseNumber = 30, Door = "N/A" in the database even though they're changed here.
    }

    context.People.Update(person);
    context.SaveChanges();
    return Results.Ok();
});

I am interested in knowing why this is the case. Is it intentional that I have to mark the address as modified so that EF Core can include it in its UPDATE SQL statement or is it a bug where it does not track changes when in reality it should? Why is the .Property(u => u.Metadata).IsModified = true; line needed explicitly?

@roji
Copy link
Member

roji commented Oct 13, 2024

This has been previously raised in #1228 and #1168; I just opened #3314 to give a more thorough explanation of the situation and to track doing this for DOM JSON mapping (not POCO). To summarize, consider switching to EF's ToJson() support rather than using the older-style POCO mapping with jsonb - that would fix this.

@roji
Copy link
Member

roji commented Oct 13, 2024

Duplicate of #3314

@roji roji marked this as a duplicate of #3314 Oct 13, 2024
@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Oct 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants