How, after all, does Tracking of EntityFramework objects?
First it is important to explain that a context exists during the life of a Controller , in the specific case that you are working using MVC. The values loaded by the Controller are only expired when the Controller in question suffers a Dispose
", making the context also suffer a Dispose
.
When loading an object, and I'll call it a record, the record is loaded with the original values of the database, and they stay there even if you change it the register. This causes that, when modifying a record, the Entity Framework knows that this record has been previously loaded and knows what to change.
The registry is usually located by its key. To understand this better, you need to understand the DbSet<T>
implementation. It is an observable collection ( ObservableCollection
). When calling , what is being done is:
Check if any collection is marked as changed;
For each record that has been marked as changed, the Entity Framework performs some logical operation to insert, update, or delete a record in the database. The executed statement is bound to SaveChanges
, a EntityState
used to identify the state of the record within the Entity Framework.
So, whenever I do a POST for an Action, which will bind a class to the Action parameter, I know I have an instance not monitored by EntityFramework, right?
Wrong. If the record has been previously loaded (in Enum
, for example), it is already being "watched". When you apply a Edit
to save the edit, the object coming from View is synchronized as follows:
context.Entry(obj).State = EntityState.Modified;
Notice that the context here is a new context, without the information of the previous request. When I say "the record has already been loaded previously", I say that it was loaded on screen, not on Controller . When you perform POST
, you are sending information and the context works optimally, ie the record is reloaded in POST
if it has not already been loaded.
In this line two things are done:
Locate a record based on another;
Update recorded registry values based on records on screen.
The Entry()
case is simpler. You are telling the context that the object does not exist, so the context considers the object as new.
As in the case of the question I referred to, why were there monitoring problems?
I'll answer the question.
What would be the most "complete" way to deal with Add
and Inserts
and not have problems with Tracking of objects?
-
No implementing repositories (the Entity Framework already implements repositories);
-
No Implementing Service Layer ( Controller is already a service layer, different, but it is);
-
No instantiating two contexts unnecessarily;
-
No selecting objects in one context and trying to save in the other;
- Using the simplest code possible, conforming to (almost) all examples illustrated here and on other specialized websites.
Enable or Disable Updates
and creation of proxies and change tracking ( LazyLoading
) affects how Tracking?
Lazy load and monitoring are independent things. One does not affect the other, and vice versa.
AutoDetectChangesEnabled
does tracking does not work. Any and all changes have to be invoked by manual methods.