Disable Entity Tracking



Disable tracking a specific entity in session

  • Tracking can be disabled for a specific entity in the session.
  • Once tracking is disabled for the entity then:
    • Any changes made to this entity will be ignored for SaveChanges.
    • Performing another Load for this entity will Not generate another call to the server.

Example

// Load a product entity, the session will track its changes
Product product = session.Load<Product>("products/1-A");

// Disable tracking for the loaded product entity
session.Advanced.IgnoreChangesFor(product);

// The following change will be ignored for SaveChanges
product.UnitsInStock += 1;

session.SaveChanges();
// Load a product entity, the session will track its changes
Product product = await asyncSession.LoadAsync<Product>("products/1-A");

// Disable tracking for the loaded product entity
asyncSession.Advanced.IgnoreChangesFor(product);

// The following change will be ignored for SaveChanges
product.UnitsInStock += 1;

await asyncSession.SaveChangesAsync();

Syntax

void IgnoreChangesFor(object entity);
Parameters Type Description
entity object Instance of entity for which changes will be ignored

Disable tracking all entities in session

  • Tracking can be disabled for all entities in the session's options.
  • When tracking is disabled for the session:
    • Method Store will Not be available (an exception will be thrown if used).
    • Calling Load or Query will generate a call to the server and create new entities instances.

using (IDocumentSession session = store.OpenSession(new SessionOptions
{
    // Disable tracking for all entities in the session's options
    NoTracking = true
}))
{
    // Load any entity, it will Not be tracked by the session
    Employee employee1 = session.Load<Employee>("employees/1-A");
    
    // Loading again from same document will result in a new entity instance
    Employee employee2 = session.Load<Employee>("employees/1-A");
    
    // Entities instances are not the same
    Assert.NotEqual(employee1, employee2);
}
using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions
{
    // Disable tracking for all entities in the session's options
    NoTracking = true
}))
{
    // Load any entity, it will Not be tracked by the session
    Employee employee1 = await asyncSession.LoadAsync<Employee>("employees/1-A");
    
    // Loading again from same document will result in a new entity instance
    Employee employee2 = await asyncSession.LoadAsync<Employee>("employees/1-A");

    // Entities instances are not the same
    Assert.NotEqual(employee1, employee2);
}

Disable tracking query results

  • Tracking can be disabled for all entities resulting from a query.

using (IDocumentSession session = store.OpenSession())
{
    // Define a query
    List<Employee> employeesResults = session.Query<Employee>()
        // Set NoTracking, all resulting entities will not be tracked
        .Customize(x => x.NoTracking())
        .Where(x => x.FirstName == "Robert")
        .ToList();

    // The following modification will not be tracked for SaveChanges
    Employee firstEmployee = employeesResults[0];
    firstEmployee.LastName = "NewName";
    
    // Change to 'firstEmployee' will not be persisted
    session.SaveChanges();
}
using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession())
{
    // Define a query
    List<Employee> employeesResults = asyncSession.Query<Employee>()
        // Set NoTracking, all resulting entities will not be tracked
        .Customize(x => x.NoTracking())
        .Where(x => x.FirstName == "Robert")
        .ToList();

    // The following modification will not be tracked for SaveChanges
    Employee firstEmployee = employeesResults[0];
    firstEmployee.LastName = "NewName";
    
    // Change to 'firstEmployee' will not be persisted
    await asyncSession.SaveChangesAsync();
}
using (IDocumentSession session = store.OpenSession())
{
    // Define a query
    List<Employee> employeesResults = session.Advanced.DocumentQuery<Employee>()
        // Set NoTracking, all resulting entities will not be tracked
        .NoTracking()
        .Where(x => x.FirstName == "Robert")
        .ToList();

    // The following modification will not be tracked for SaveChanges
    Employee firstEmployee = employeesResults[0];
    firstEmployee.LastName = "NewName";
    
    // Change to 'firstEmployee' will not be persisted
    session.SaveChanges();
}
using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession())
{
    // Define a query
    List<Employee> employeesResults = asyncSession.Advanced.AsyncDocumentQuery<Employee>()
        // Set NoTracking, all resulting entities will not be tracked
        .NoTracking()
        .Where(x => x.FirstName == "Robert")
        .ToList();

    // The following modification will not be tracked for SaveChanges
    Employee firstEmployee = employeesResults[0];
    firstEmployee.LastName = "NewName";
    
    // Change to 'firstEmployee' will not be persisted
    await asyncSession.SaveChangesAsync();
}

Customize tracking in conventions

  • You can further customize and fine-tune which entities will not be tracked
    by configuring the ShouldIgnoreEntityChanges convention method on the document store.
  • This customization rule will apply to all sessions opened for this document store.

Example

using (var store = new DocumentStore()
{
    // Define the 'ignore' convention on your document store
    Conventions =
    {
        ShouldIgnoreEntityChanges =
            // Define for which entities tracking should be disabled 
            // Tracking will be disabled ONLY for entities of type Employee whose FirstName is Bob
            (session, entity, id) => (entity is Employee e) &&
                                     (e.FirstName == "Bob")
    }
}.Initialize())
{
    using (IDocumentSession session = store.OpenSession())
    {
        var employee1 = new Employee { Id = "employees/1", FirstName = "Alice" };
        var employee2 = new Employee { Id = "employees/2", FirstName = "Bob" };

        session.Store(employee1);      // This entity will be tracked
        session.Store(employee2);      // Changes to this entity will be ignored

        session.SaveChanges();         // Only employee1 will be persisted

        employee1.FirstName = "Bob";   // Changes to this entity will now be ignored
        employee2.FirstName = "Alice"; // This entity will now be tracked

        session.SaveChanges();         // Only employee2 is persisted
    }
}

Syntax

public Func<InMemoryDocumentSessionOperations, object, string, bool> ShouldIgnoreEntityChanges;
Parameter Description
InMemoryDocumentSessionOperations The session for which tracking is to be disabled
object The entity for which tracking is to be disabled
string The entity's document ID
Return Type Description
bool true - Entity will Not be tracked
false - Entity will be tracked