Data Access has been discontinued. Please refer to this page for more information.

Persistent States and Transitions

This article will present to you the states and the transitions an object existing in the database could go through. It describes the main processes that the object can participate in:

Additionally, a special attention is dedicated to the NotLoaded state.

The code snippets in this article are based on the Northwind sample database.

Update A Record in The Database

Let's consider the scenario where a given record in the database needs to be updated. The states and the transitions a corresponding in-memory object has to go through are demonstrated in the following code snippet:

using (FluentModel dbContext = new FluentModel())
{
    //Query for an object
    Category someCategory = dbContext.Categories.First();
    //The initial state is Clean. 
    //The returned value is MaskLoaded|MaskManaged|MaskNoMask
    ObjectState state = dbContext.GetState(someCategory);
    //Edit a property
    someCategory.CategoryName = "New Name";
    //The state changes to Dirty. 
    //The returned value is MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory);
    //Persist the changes
    dbContext.SaveChanges();
    //The state changes to NotLoaded. 
    //The returned value is MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory);
}
Using dbContext As New FluentModel()
    'Query for an object
    Dim someCategory As Category = dbContext.Categories.First()
    'The initial state is Clean. 
    'The returned value is MaskLoaded|MaskManaged|MaskNoMask
    Dim state As ObjectState = dbContext.GetState(someCategory)
    'Edit a property
    someCategory.CategoryName = "New Name"
    'The state changes to Dirty. 
    'The returned value is MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory)
    'Persist the changes
    dbContext.SaveChanges()
    'The state changes to NotLoaded. 
    'The returned value is MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory)
End Using

A detailed description of the object states is available in the Object Life-cycle Overview article.

When a SELECT statement returns an object that exists in the database, its initial state is Clean (the context is tracking the changes about that object and the relevant data are loaded in-memory). Here, if the transaction state changes or the execution of the process is terminated, the object's data will be unloaded from the memory and someCategory will be transferred to NotLoaded state.

When a property of someCategory changes its value in-memory, its state will become Dirty (on SaveChanges() an UPDATE statement will be generated about it). At that point, if the transaction is rolled back or the execution of the process is terminated, no new data will be persisted to the database and the object state will change to NotLoaded.

If the transaction is committed, however, the new values will be persisted to the database and the object state will become NotLoaded.

Delete A Record from The Database

Let's take a look at the scenario where a given record in the database needs to be deleted. The states and the transitions a corresponding in-memory object has to go through are demonstrated in the following code snippet:

using (FluentModel dbContext = new FluentModel())
{
    //Query for an object
    Category someCategory = dbContext.Categories.First();
    //The initial state is Clean. 
    //The returned value is MaskLoaded|MaskManaged|MaskNoMask
    ObjectState state = dbContext.GetState(someCategory);
    //Remove the object from the context
    dbContext.Delete(someCategory);
    //The state changes to Deleted. 
    //The returned value is MaskDeleted|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory);
    //Presist the changes
    dbContext.SaveChanges();
    //The state changes to NotLoaded. 
    //The returned value is MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory);
}
Using dbContext As New FluentModel()
    'Query for an object
    Dim someCategory As Category = dbContext.Categories.First()
    'The initial state is Clean. 
    'The returned value is MaskLoaded|MaskManaged|MaskNoMask
    Dim state As ObjectState = dbContext.GetState(someCategory)
    'Remove the object from the context
    dbContext.Delete(someCategory)
    'The state changes to Deleted. 
    'The returned value is MaskDeleted|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory)
    'Presist the changes
    dbContext.SaveChanges()
    'The state changes to NotLoaded. 
    'The returned value is MaskManaged|MaskNoMask
    state = dbContext.GetState(someCategory)
End Using

A detailed description of the object states is available in the Object Life-cycle Overview article.

When a SELECT statement returns an object that exists in the database, its initial state is Clean (the context is tracking the changes about that object and the relevant data are loaded in-memory). Here, if the transaction state changes or the execution of the process is terminated, the object's data will be unloaded from the memory and someCategory will be transferred to NotLoaded state.

When someCategory is passed to the Delete() method of the context, its state will become Deleted (on SaveChanges() a DELETE statement will be generated about it). At that point, if the transaction is rolled back or the execution of the process is terminated, no statements will be executed against the database and the object's state will change to NotLoaded.

If the transaction is committed, however, the corresponding record in the database will be deleted, the context will not track any changes about that the object and its state will become NotManaged.

The NotLoaded State

If you take a look at the Persistent States and Transitions diagram in this article and the Persistent New States and Transitions diagram in the previous one, you will notice that after INSERT and UPDATE statements, the corresponding objects end up in the NotLoaded state.

Generally, this state means that the object is managed by the context, exists in memory but the data from its properties are unloaded from the memory. In real-life scenarios when the context is not disposed immediately after the transaction is committed\rolled back, the user through the UI may need to perform additional actions.