Disable Entity Tracking



Disable tracking changes for a specific entity

  • You can prevent the session from persisting changes made to a specific entity by using ignoreChangesFor.
  • Once changes are ignored for the entity:
    • Any modifications made to the entity will be ignored by saveChanges.
    • The session will still keep a reference to the entity to avoid repeated server requests.
      Performing another load for the same entity will Not generate another call to the server.

Example

const session = documentStore.openSession();        

// Load a product entity - the session will track the entity by default
const product = await session.load("products/1-A");

// Call 'ignoreChangesFor' to instruct the session to ignore changes made to this entity
session.advanded.ignoreChangesFor(product);

// The following change will be ignored by SaveChanges - it will not be persisted
product.unitsInStock += 1;

await session.saveChanges();

Syntax

session.advanced.ignoreChangesFor(entity);
Parameter 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.

const session = documentStore.openSession({
    // Disable tracking for all entities in the session's options
    noTracking: true
});

// Load any entity, it will Not be tracked by the session
const employee1 = await session.load("employees/1-A");

// Loading again from same document will result in a new entity instance
const employee2 = await session.load("employees/1-A");

// Entities instances are not the same
assert.notStrictEqual(company1, company2);

// Calling saveChanges will throw an exception
await session.saveChanges();

Disable tracking query results

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

const session = documentStore.openSession();

// Define a query
const employeesResults = await session.query({ collection: "employees" })
    .whereEquals("FirstName", "Robert")
     // Set noTracking, all resulting entities will not be tracked
    .noTracking()
    .all();

// The following modification will not be tracked for saveChanges
const firstEmployee = employeesResults[0];
firstEmployee.lastName = "NewName";

// Change to 'firstEmployee' will not be persisted
session.saveChanges();

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

const customStore = new DocumentStore();

// Define the 'ignore' convention on your document store
customStore.conventions.shouldIgnoreEntityChanges =
    (sessionOperations, entity, documentId) => {
        // Define for which entities tracking should be disabled 
        // Tracking will be disabled ONLY for entities of type Employee whose firstName is Bob
        return entity instanceof Employee && entity.firstName === "Bob";
    };
customStore.initialize();

const session = customStore.openSession();

const employee1 = new Employee();
employee1.firstName = "Alice";

const employee2 = new Employee();
employee2.firstName = "Bob";

await session.store(employee1, "employees/1-A"); // This entity will be tracked
await session.store(employee2, "employees/2-A"); // Changes to this entity will be ignored

await 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

store.conventions.shouldIgnoreEntityChanges = (sessionOperations, entity, documentId) => {
    // Write your logic
    // return value:
    //     true - entity will not be tracked 
    //     false - entity will be tracked
}
Parameter Type Description
sessionOperations InMemoryDocumentSessionOperations The session for which tracking is to be disabled
entity object The entity for which tracking is to be disabled
documentId string The entity's document ID
Return Type Description
boolean true - Entity will Not be tracked
false - Entity will be tracked

Using 'include' in a noTracking session will throw

  • Attempting to use include in a noTracking session will throw an exception.

  • Like other entities in a noTracking session, the included items are not tracked and will not prevent additional server requests during subsequent load operations for the same data. To avoid confusion, include operations are disallowed during non-tracking session actions such as load or query.

  • This applies to all items that can be included -
    e.g., documents, compare-exchange items, counters, revisions, and time series.


Include when loading:

const session = documentStore.openSession({
    // Working with a non-tracking session
    noTracking: true
});

try {
    // Trying to include a related document when loading a document will throw
    const product = await session
        .include("supplier")
        .load("products/1-A");
}
catch (error) {
    // An exception is expected here
}

Include when querying:

const session = documentStore.openSession({
    // Working with a non-tracking session
    noTracking: true
});

try {
    // Trying to include related documents in a query will throw
    const products = await session
        .query({ collection: 'products' })
        .include("supplier")
        .all();
}
catch (error) {
    // An exception is expected here
}