0

I'm calling DbContext.SaveChangesAsync() to save my objects to the database. This takes about 120 ms.

If an event changes an tracked object's property during this time, this change is neither directly saved to database nor tracked by the EF Core ChangeTracker to save it later.

That means, that if I call DbContext.SaveChangesAsync() later again, the new property value is still not saved to the database because the EF Core ChangeTracking doesn't see this change.

I was expecting that DbContext.SaveChangesAsync() can't save changes to the database that are made during the operation. But I was expecting that the EF Core ChangeTracker would track this change correctly to make it possible to later save it to the database.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
joru1407
  • 1
  • 1
  • Do you use transactions? – Fildor Feb 26 '23 at 19:49
  • Are you sure you are tracking it? you should try to see if that change is actually really being tracked by looking at the change tracker. – Jakub Holovsky Feb 26 '23 at 20:07
  • Because `.SaveChanges` is effectively `.DetectChanges` => sql => `.AcceptAllChanges`. – Jeremy Lakeman Feb 27 '23 at 00:37
  • I'm not using transactions (beside the automatic ones) and I'm shure the object itself is tracked. If i do some changes to it later, they're correctly detected. @JeremyLakeman I think that's my problem. The SQL operation between `.DetectChanges` and `.AcceptAllChanges` takes some time. And all changes made during this are accepted without beeing saved. – joru1407 Feb 27 '23 at 04:53
  • How do you change the properties? More details of your code should be helpful. – sambath999 Mar 02 '23 at 10:28

1 Answers1

2

One of possible solutions is to mark the object as Modified explicitly. There is an Entry() method to obtain an EntityEntry for the object you want to modify, and then calling the EntityEntry.State property to set its state to Modified:

db.Entry(yourEntity).State = EntityState.Modified;

Note: some more details can be found by the question and documentation.

Multiple DbContext instances might also be used to switch between them for such cases as EF Core implements optimistic concurrency, however IMO it might cause more problems than benefits without deep understanding. So everyone should use it carefully as it can lead to unexpected behaviour and issues.

Ivan Vydrin
  • 273
  • 7
  • Thanks. Also if I mark it as *Modified* explicitly, the changes seem to get accepted without beeing saved so that the object isn't marked as modified aftewards anymore. See above comments from @Jeremy and me. – joru1407 Feb 27 '23 at 04:56
  • @joru1407 There is a possibility to handle the ChangeTracker manually as well: `context.ChangeTracker.AutoDetectChangesEnabled = false;` in the beginning of method, mark the Entity as modified explicitly, and turn AutoDetection on back after `SaveChanges()`. Please, try it and LMK if it helps. I didn't test it before, however it potentially might fix the gap between Detecting and Accepting. – Ivan Vydrin Feb 27 '23 at 05:23