How to Check for Session Changes



Check for session changes

  • The session's advanced property HasChanges indicates whether any entities were added, modified, or deleted within the session.

  • Note: The HasChanges property is cleared after calling SaveChanges().


using (var session = store.OpenSession())
{
    // No changes made yet - 'HasChanges' will be FALSE 
    Assert.False(session.Advanced.HasChanges);
    
    // Store a new entity within the session
    session.Store(new Employee { FirstName = "John", LastName = "Doe" });
    
    // 'HasChanges' will now be TRUE 
    Assert.True(session.Advanced.HasChanges);
    
    // 'HasChanges' will reset to FALSE after saving changes 
    session.SaveChanges();
    Assert.False(session.Advanced.HasChanges);
}

Get session changes

  • Use the session's advanced method WhatChanged() to get all changes made to all the entities tracked by the session.

  • For each entity that was modified, the details will include:

    • The name and path of the changed field
    • Its old and new values
    • The type of change
  • Note: WhatChanged() reports changes made prior to calling SaveChanges().
    Calling it immediately after SaveChanges will return no results, as the changes are cleared.


Example I

using (var session = store.OpenSession())
{
    // Store (add) new entities, they will be tracked by the session
    session.Store(new Employee { FirstName = "John", LastName = "Doe" }, "employees/1-A");
    session.Store(new Employee { FirstName = "Jane", LastName = "Doe" }, "employees/2-A");

    // Call 'WhatChanged' to get all changes in the session
    IDictionary<string, DocumentsChanges[]> changes = session.Advanced.WhatChanged();
    Assert.Equal(changes.Count, 2); // 2 entities were added
    
    // Get the change details for an entity, specify the entity ID
    DocumentsChanges[] changesForEmployee = changes["employees/1-A"];
    Assert.Equal(changesForEmployee.Length, 1); // a single change for this entity (adding)
    
    // Get the change type
    DocumentsChanges.ChangeType changeType = changesForEmployee[0].Change;
    Assert.Equal(changeType, DocumentsChanges.ChangeType.DocumentAdded);
    
    session.SaveChanges();
}
Example II

using (var session = store.OpenSession())
{
    // Load the entities, they will be tracked by the session
    Employee employee1 = session.Load<Employee>("employees/1-A");
    Employee employee2 = session.Load<Employee>("employees/2-A");
    
    // Modify entities
    employee1.FirstName = "Jim";
    employee1.LastName = "Brown";
    employee2.LastName = "Smith";
    
    // Delete an entity
    session.Delete(employee2);

    // Call 'WhatChanged' to get all changes in the session
    IDictionary<string, DocumentsChanges[]> changes = session.Advanced.WhatChanged();
    
    // Get the change details for an entity, specify the entity ID
    DocumentsChanges[] changesForEmployee = changes["employees/1-A"];
    
    Assert.Equal(changesForEmployee[0].FieldName, "FirstName");                           // Field name
    Assert.Equal(changesForEmployee[0].FieldNewValue, "Jim");                             // New value
    Assert.Equal(changesForEmployee[0].Change, DocumentsChanges.ChangeType.FieldChanged); // Change type
    
    Assert.Equal(changesForEmployee[1].FieldName, "LastName");
    Assert.Equal(changesForEmployee[1].FieldNewValue, "Brown");
    Assert.Equal(changesForEmployee[1].Change, DocumentsChanges.ChangeType.FieldChanged);
    
    // Note: for employee2 - even though the LastName was changed to 'Smith',
    // the only reported change is the latest modification, which is the delete action. 
    changesForEmployee = changes["employees/2-A"];
    Assert.Equal(changesForEmployee[0].Change, DocumentsChanges.ChangeType.DocumentDeleted);
    
    session.SaveChanges();
}

Syntax

// HasChanges
bool HasChanges { get; }
// WhatChanged
IDictionary<string, DocumentsChanges[]> WhatChanged();
Return value
IDictionary<string, DocumentsChanges[]> Dictionary containing list of changes per document ID

public class DocumentsChanges
{
    public object FieldOldValue { get; set; }  // Previous field value
    public object FieldNewValue { get; set; }  // Current field value
    public ChangeType Change { get; set; }     // Type of change that occurred
    public string FieldName { get; set; }      // Name of field on which the change occurred
    public string FieldPath { get; set; }      // Path of field on which the change occurred
    public string FieldFullName { get; }       // Path + Name of field on which the change occurred
}

public enum ChangeType
{
    DocumentDeleted,
    DocumentAdded,
    FieldChanged,
    NewField,
    RemovedField,
    ArrayValueChanged,
    ArrayValueAdded,
    ArrayValueRemoved
}