Object Life-Cycle Overview
The core feature of Telerik Data Access during runtime is to generate SQL statements based on the persistent objects (instances of the persistent classes) tracked by a given instance of the OpenAccessContext class. In order to do so it collects information about the objects' origin and the actions performed on them from the moment the context is instantiated through the commitment\rollback of the transaction to the disposal of the context. Based on this information Telerik Data Access forms a state for each object and uses it when the statements are generated (e.g. during a call to the SaveChanges() method). Additionally, Telerik Data Access exposes the object state to the developers (through the ObjectState enumeration and the GetState() methods).
This article will introduce you to:
- Object States
- How to Retrieve an Object State
- Interpretation of ObjectState Values
- Transitions between The Object States
- Object Life-Cycle
Object States
The objects can be in one of the following states:
- NotManaged - this is the state of an in-memory object that is not managed by the context; the context is not aware of it and will not issue any statements about it during SaveChanges().
- NotLoaded - this is the state of an in-memory object that is managed by the context but due to call to the SaveChanges() method its data is unloaded from the memory.
- Clean - this is an object that was just retrieved from the database and is not yet edited (the values of the properties are not changed). No statement will be issued about it on SaveChanges()
- Dirty - this is an object that was retrieved from the database and at least one of its properties is edited. An UPDATE statement will be issued about it on SaveChanges()
- New - this is the state of an object that has just been added to the context through the OpenAccessContext.Add() method. On SaveChanges() an INSERT statement will be generated about it
- Deleted - this is an object retrieved from the database and passed to the OpenAccessContext.Delete() method for removal. On SaveChanges() a DELETE statement will be issued about it
- NewDeleted - this is an in-memory object that has just been added and deleted from the context. In other words, it has been passed to the OpenAccessContext.Add() and OpenAccessContext.Delete() methods of one and the same OpenAccessContext instance. On SaveChanges() no statement will be issued about it.
-
DetachedClean - this is the state of an object that has just been created with the help of the CreateDetachedCopy
() method based on a Clean object. -
DetachedDirty - this is the state of a DetachedClean object that has just been edited (at least one of its properties is changed) or of an object that has just been created with the help of the CreateDetachedCopy
() method based on a Dirty object. - DetachedNew - this is the state of an object that is new to a given instance of OpenAccessContext but has just been associated with a navigation property of a detached copy of another object.
How to Retrieve an Object State
You can obtain the state of an object in two ways:
-
OpenAccessContextBase.GetState() - this method is applicable within the life of a given instance of the context. For example:
using (FluentModel dbContext = new FluentModel()) { //Query for an object Category someCategory = dbContext.Categories.First(); //Determine the object state ObjectState state = dbContext.GetState(someCategory); }
Using dbContext As New FluentModel() 'Query for an object Dim someCategory As Category = dbContext.Categories.First() 'Determine the object state Dim state As ObjectState = dbContext.GetState(someCategory) End Using
-
OpenAccessContext.PersistenceState.GetState() - this static method allows you to track objects retrieved through a context that is already disposed. For example:
Category someCategory = null; using (FluentModel dbContext = new FluentModel()) { //Query for an object someCategory = dbContext.Categories.First(); } //Determine the object state ObjectState categoryState = OpenAccessContext.PersistenceState.GetState(someCategory);
Dim someCategory As Category = Nothing Using dbContext As New FluentModel() 'Query for an object someCategory = dbContext.Categories.First() End Using 'Determine the object state Dim categoryState As ObjectState = OpenAccessContext.PersistenceState.GetState(someCategory)
Interpretation of ObjectState Values
- MaskDeleted - Mask representing all objects marked as to be deleted.
- MaskNew - Mask representing all objects marked as to be inserted.
- MaskDirty - Mask representing all objects marked as changed.
- MaskLoaded - Mask representing all objects marked as loaded.
- MaskManaged - Mask representing all objects managed by a context.
- MaskNoMask - As an only value retrieved by GetState(), MaskNoMask means that the object is not managed by a context. In combination with the other masks, it means that the entire value is not a mask.
- Detached - Mask representing all objects detached from the context.
The state of a given object returned by the GetState() methods can be one of the following combinations:
NotManaged | MaskNoMask | ||||||
NotLoaded | MaskManaged | MaskNoMask | |||||
Clean | MaskLoaded | MaskManaged | MaskNoMask | ||||
Dirty | MaskDirty | MaskLoaded | MaskManaged | MaskNoMask | |||
New | MaskNew | MaskDirty | MaskLoaded | MaskManaged | MaskNoMask | ||
Deleted | MaskDeleted | MaskDirty | MaskLoaded | MaskManaged | MaskNoMask | ||
NewDeleted | MaskDeleted | MaskNew | MaskDirty | MaskLoaded | MaskManaged | MaskNoMask | |
DetachedClean | MaskLoaded | MaskManaged | MaskNoMask | Detached | |||
DetachedDirty | MaskDirty | MaskLoaded | MaskManaged | MaskNoMask | Detached | ||
DetachedNew | MaskNew | MaskDirty | MaskLoaded | MaskManaged | MaskNoMask | Detached |
Transitions between The Object States
The following table shows the possible operations that can be applied on an object in a given state and the new state of the object after that:
State | Operation | New State |
NotManaged | Add to context | New |
NotLoaded | Query the database Remove from context |
Clean Deleted |
Clean | Edit a property Remove from context Transaction commit or rollback |
Dirty Deleted NotLoaded |
Dirty | Remove from context Transaction commit or rollback |
Deleted NotLoaded |
New | Remove from context Transaction commit Transaction rollback |
NewDeleted NotLoaded NotManaged |
Deleted | Transaction commit Transaction rollback |
NotLoaded NotManaged |
NewDeleted | Transaction commit Transaction rollback |
NotManaged |
DetachedClean | Edit a property | DetachedDirty |
Object Life-Cycle
The following articles will present to you the state transitions depending on the origin of the objects in-memory: