Entity Framework and DbContext - Object Tracking

I am a bit confused about using DbContext in Entity Framework. Here's a script I'm confused about.

  • I am using the linq query from dbcontext to get the data. Sort of:

    List<Transactions> transactions = DefaultContext.Transactions.ToList(); 
  • Then I update the column in one of the transactions returned in this query directly in the database.

  • Then I call again:

     List<Transactions> transactions = DefaultContext.Transactions.ToList(); 

When the list comes back this time, it does not reflect the updates / changes that I made when I started the update statement, unless I go through all my transactions and reload them:

 foreach (DbEntityEntry<Transactions> item in DefaultContext.ChangeTracker.Entries<Transactions>()) { DefaultContext.Entry<Transactions>(item.Entity).Reload(); } 

Is this normal behavior? I assume that in my initial request they are bound to the context of the object. Then, when I request a second time, it does not travel to the database and simply pulls objects out of the context of the object, unless I clear / disconnect or reload individual objects.

+2
source share
3 answers

This is also normal with the fixed behavior of the DbContext API, because for some very strange reason, neither DbSet nor DbSet set the MergeOption property. In the case of the ObjectContext API, you can set the behavior of MergeOption to ObjectSet and ObjectQuery . Therefore, if you want to update the values ​​from the database (and lose your changes), you can do:

 ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; ObjectSet<Transactions> set = objectContext.CreateObjectSet<Transactions>(); set.MergeOption = MergeOption.OverwriteChanges; List<Transactions> transactions = set.ToList(); 

If you just want to update your transactions, but don't want to lose your changes, you can use MergeOption.PreserveChanges .

+8
source

It depends on MergeOption DefaultContext.Transactions request. The default value of AppendOnly will not overwrite objects already in your context. You can change this to OverwriteChanges to get the behavior you expect.

+2
source

In connection with the foregoing, this is the place where I landed when I had the same error. But in my case, I wanted to set the Combine Option to No Tracking . I came across this when I had an excel export method that tried to disable IQueryable object tracking. Going through a lot of data that I was not going to change, I do not need to track changes.

A line of code like the one below would fail if you tried to apply some IQueryables to the ObjectQuery class (but succeed on others.)

 var y = ((ObjectQuery)query).MergeOption = MergeOption.NoTracking; 

Instead, I replaced it with AsNoTracking

 query = query.AsNoTracking(); 

Relating to the original question, this would potentially be similar to the following: the extension method in DBQuery added to System.Data.Entity

 List<Transactions> transactions = DefaultContext.Transactions.AsNoTracking().ToList(); 

Prefabricated article: https://msdn.microsoft.com/en-us/library/hh949853(v=vs.113).aspx

0
source

Source: https://habr.com/ru/post/1440108/


All Articles