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

New Objects States and Transitions

This article will present to you the states and the transitions a new object goes through before being persisted to the database. It describes the two main processes that a new object can participate in:

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

Insert into The Database

Let's consider a general scenario where a new category will be added to the Category table and to take a look at the changes in the state of newCategory:

using (FluentModel dbContext = new FluentModel())
{
    //Create a new category
    Category newCategory = new Category()
    {
        CategoryName = "NewCategory",
        Description = "Description",
    };
    //The initial state is NotManaged. 
    //The returned value is MaskNoMask
    ObjectState state = dbContext.GetState(newCategory);
    //Add the new category to the context
    dbContext.Add(newCategory);
    //The state changes to New. 
    //The returned value is MaskNew|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory);
    //Persist data to the database
    dbContext.SaveChanges();
    //The state changes to NotLoaded. 
    //The returned value is MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory);
}
Using dbContext As New FluentModel()
    'Create a new category
    Dim newCategory As New Category() With 
    {
        .CategoryName = "NewCategory", 
        .Description = "Description"
    }
    'The initial state is NotManaged. 
    'The returned value is MaskNoMask
    Dim state As ObjectState = dbContext.GetState(newCategory)
    'Add the new category to the context
    dbContext.Add(newCategory)
    'The state changes to New. 
    'The returned value is MaskNew|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory)
    'Persist data to the database
    dbContext.SaveChanges()
    'The state changes to NotLoaded. 
    'The returned value is MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory)
End Using

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

The newCategory object starts as NotManaged, the Add() method changes its state to New which means that on SaveChanges() an INSERT statement will be generated about it. At that point, once the transaction is committed, the data will be persisted to the database and the newCategory state will be NotLoaded.

In scenarios where an object is in a NotLoaded state, if even one of its properties is accessed a SELECT statement will be generated in order to populate it with data (the persistent states are discussed in the Persistent States and Transitions article).

If the transaction is rolled back or the execution of the process is terminated before the call to SaveChanges() the object will be returned to NotManaged and no data for the new category will be transferred to the database.

A common version of the described scenario would be to edit a property of the newly created object before it is actually persisted to the database. Here, it is irrelevant whether the edit is before or after the call to the Add() method because it does not change the state of the object. For example:

using (FluentModel dbContext = new FluentModel())
{
    //Create a new category
    Category newCategory = new Category()
    {
        CategoryName = "NewCategory",
        Description = "Description",
    };
    //Add the new category to the context
    dbContext.Add(newCategory);
    //The state of newCategory is New
    ObjectState state = dbContext.GetState(newCategory);
    //A property is updated
    newCategory.CategoryName = "New";
    //The state of newCategory remains New
    state = dbContext.GetState(newCategory);
    //Persist data to the database
    dbContext.SaveChanges();
}
Using dbContext As New FluentModel()
    'Create a new category
    Dim newCategory As New Category() With 
    {
        .CategoryName = "NewCategory", 
        .Description = "Description"
    }
    'Add the new category to the context
    dbContext.Add(newCategory)
    'The state of newCategory is New
    Dim state As ObjectState = dbContext.GetState(newCategory)
    'A property is updated
    newCategory.CategoryName = "New"
    'The state of newCategory remains New
    state = dbContext.GetState(newCategory)
    'Persist data to the database
    dbContext.SaveChanges()
End Using

Again if the transaction is committed data will be persisted to the database and the newCategory state will be NotLoaded and if it is rolled back or the execution of the process is terminated before the call to SaveChanges() the object will be returned to the NotManaged state and no data will be persisted.

Remove from A Transaction

Let's consider the scenario where initially a new category is created in order to be inserted to the database but a decision was taken to not persist it with the current transaction.

using (FluentModel dbContext = new FluentModel())
{
    //Create a new category
    Category newCategory = new Category()
    {
        CategoryName = "NewCategory",
        Description = "Description",
    };
    //The initial state is NotManaged. 
    //The returned value is MaskNoMask
    ObjectState state = dbContext.GetState(newCategory);
    //Add the new category to the context
    dbContext.Add(newCategory);
    //The state changes to New. 
    //The returned value is MaskNew|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory);
    //Delete the category from the context
    dbContext.Delete(newCategory);
    //The state changes to NewDeleted. 
    //The returned value is MaskDeleted|MaskNew|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory);
    //Persist data to the database
    dbContext.SaveChanges();
    //The state changes to NotManaged. 
    //The retuned value is MaskNoMask
    state = dbContext.GetState(newCategory);
}
Using dbContext As New FluentModel()
    'Create a new category
    Dim newCategory As New Category() With 
    {
        .CategoryName = "NewCategory", 
        .Description = "Description"
    }
    'The initial state is NotManaged. 
    'The returned value is MaskNoMask
    Dim state As ObjectState = dbContext.GetState(newCategory)
    'Add the new category to the context
    dbContext.Add(newCategory)
    'The state changes to New. 
    'The returned value is MaskNew|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory)
    'Delete the category from the context
    dbContext.Delete(newCategory)
    'The state changes to NewDeleted. 
    'The returned value is MaskDeleted|MaskNew|MaskDirty|MaskLoaded|MaskManaged|MaskNoMask
    state = dbContext.GetState(newCategory)
    'Persist data to the database
    dbContext.SaveChanges()
    'The state changes to NotManaged. 
    'The retuned value is MaskNoMask
    state = dbContext.GetState(newCategory)
End Using

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

The newCategory object starts as NotManaged, the Add() method changes its state to New which means that on SaveChanges() an INSERT statement should be generated about it. At that point, if the transaction is rolled back or the execution of the process is terminated before the call to SaveChanges() the object will be returned to NotManaged (no data for the new category would be transferred to the database).

Passing the object to the Delete() method changes its state to NewDeleted which means that during SaveChanges() no statements will be generated for the object, no data will be transferred to the database and the final object state will be NotManaged. At this point, the outcome from the transaction is irrelevant to this object.