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

Proper way of editing properties in jsonb #1168

Closed
skynet2 opened this issue Dec 16, 2019 · 1 comment
Closed

Proper way of editing properties in jsonb #1168

skynet2 opened this issue Dec 16, 2019 · 1 comment

Comments

@skynet2
Copy link

skynet2 commented Dec 16, 2019

Hello,
As far as CLR types are not tracked by ef core (#1117)
What's the proper way of updating inner entities?

models.cs

    public class CouponConfiguration
    {
        public int MaxEvents { get; set; }
    }
    public class Configurations
    {
        public int Id { get; set; }
        public CouponConfiguration Coupon { get; set; }
        public int CreatedBy { get; set; }
        public DateTime CreatedAt { get; set; }
    }

context.cs

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
          modelBuilder.Entity<Configurations>(builder =>
            {
                builder.HasKey(x => x.Id);

                builder.Property(x => x.Coupon).HasColumnType("jsonb");
                builder.Property(x => x.CreatedBy).IsRequired();
                builder.Property(x => x.CreatedAt).IsRequired();
            });
         }

test.cs

[Test]
        public void CanEditConfiguration()
        {
            var provider = Setup.ServiceProvider.CreateScope().ServiceProvider;

            var obj = new Configurations()
            {
                Coupon = new CouponConfiguration()
                {
                    MaxEvents = 1000
                }
            };

            var context = provider.GetService<PartnerContext>();
            
            context.Configurations.Add(obj);

            context.SaveChanges();

            try
            {
                obj.Coupon.MaxEvents = 100;
                context.Entry(obj.Coupon).State = EntityState.Modified;
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                var xx2 = 0;
            }


            var xx = 0;
        }

Saving works without any issues. But once I try to edit data, I`m setting Modified state manually.

context.Entry(obj.Coupon).State = EntityState.Modified;

And that action causes exception: System.InvalidOperationException: The entity type 'CouponConfiguration' was not found. Ensure that the entity type has been added to the model.
It`s possible to bypass that exception when setting the whole entity to state modified, then update works.

context.Entry(obj).State = EntityState.Modified;

But doing that will cause ef core to update ALL properties, instead of only one inner object.

Is it possible to bypass that limitation\exception somehow?

Thanks,
Stas

@roji
Copy link
Member

roji commented May 24, 2020

Going over old issues and came across this - sorry I haven't responded earlier.

CouponConfiguration isn't an entity type known by EF Core, since it's mapped to a json column. In other words, EF Core doesn't track the individual properties contained inside CouponConfiguration.

You can manage the change tracking state of individual properties as follows:

ctx.Entry(obj).Property(o => o.Coupon).IsModified = true;

This should make only your jsonb property as changed, and send and UPDATE only for that when you call SaveChanges.

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