Skip to main content
Evict a Single Entity from a Session

Evict a Single Entity from a Session

  • By default, the session tracks all entities that it has either stored, loaded, or queried.
    Any changes made to these entities are automatically persisted when SaveChanges is called.

  • Use the Evict method to remove a specific entity from the session's tracking before calling SaveChanges.
    Eviction stops the session from tracking the entity, removes it from the identity map and internal cache,
    and cancels any pending operations for that entity (e.g., Store, Delete).

  • This article explains how to evict a single entity from the session.
    To evict all tracked entities and clear all pending operations, use the Clear method instead.
    To prevent an entity from being tracked, see DisableTracking.

  • In this article:


Evict an entity before saving

  • Calling Evict on an entity that is stored removes it from the session’s tracking and cancels the pending store operation.
    As a result, the entity will not be saved to the database when SaveChanges is called.
  • This can be useful if you’ve staged an entity to be stored, but then decide to discard it before committing changes.
using (var session = store.OpenSession())
{
Employee employee1 = new Employee { FirstName = "John", LastName = "Doe" };
Employee employee2 = new Employee { FirstName = "Jane", LastName = "Doe" };

// Store both employees in the session
// The session begins tracking both employee entities
session.Store(employee1, "employees/1");
session.Store(employee2, "employees/2");

// Evict employee1
// This removes employee1 from the session's tracking
// and cancels its pending store operation
session.Advanced.Evict(employee1);

// Only employee2 will be saved
session.SaveChanges();
}

Evict an entity to force reload from server

  • Calling Evict on an entity that was previously loaded removes it from the session’s tracking.
    The next time you call Load for that entity, RavenDB will fetch it from the server instead of returning the cached version.
  • This can be useful if you want to ensure you're working with the latest version of a document,
    for example, if you expect the document was modified outside the session.
using (var session = store.OpenSession())
{
// Load an entity from the server
// The session begins tracking the loaded entity
Employee employee = session.Load<Employee>("employees/1");
Console.WriteLine("number of requests = " + session.Advanced.NumberOfRequests); // 1

// Loading the same entity again does NOT trigger a server call
employee = session.Load<Employee>("employees/1");
Console.WriteLine("number of requests = " + session.Advanced.NumberOfRequests); // 1

// Evict the entity
// This removes it from the session's tracking
session.Advanced.Evict(employee);

// Loading the entity now DOES trigger a server call
employee = session.Load<Employee>("employees/1");
Console.WriteLine("number of requests = " + session.Advanced.NumberOfRequests); // 2
}

Evict an entity from the session's delete queue

  • Calling Evict on an entity that was previously marked for deletion removes it from the session's delete queue.
    As a result, the deletion will not be sent to the server when SaveChanges is called.
  • This can be useful if you need to revert a pending deletion before committing changes.
using (var session = store.OpenSession())
{
var employee1 = session.Load<Employee>("employees/1");
var employee2 = session.Load<Employee>("employees/2");

// Mark both employees for deletion
session.Delete(employee1);
session.Delete(employee1);

// Remove employee1 from tracking and from delete queue
session.Advanced.Evict(employee1);

// Only employee2 will be deleted
session.SaveChanges();
}

Limitations

  • Evict cannot be called from within an OnBeforeStore or OnBeforeDelete event handler.
    Attempting to do so will throw an exception.
  • This is a design limitation intended to prevent changes to the session's internal state during event handlers that are triggered by SaveChanges. For example:
using (var session = store.OpenSession())
{
session.Store(new Employee() { FirstName = "Foo1" }, "employees/1");
session.Store(new Employee() { FirstName = "Foo2" }, "employees/2");
session.SaveChanges();
}

using (var session = store.OpenSession())
{
var employee2 = session.Load<Employee>("employees/2");

// Register an event handler that will be called before any document is saved during SaveChanges
session.Advanced.OnBeforeStore += delegate (object sender, BeforeStoreEventArgs args)
{
try
{
args.Session.Evict(employee2);
}
catch (InvalidOperationException e)
{
// An exception is thrown:
// "Cannot Evict entity during OnBeforeStore..."
}
};

session.Store(new Employee { FirstName = "Foo3" }, "employees/3");

// SaveChanges triggers the 'OnBeforeStore' event
session.SaveChanges();
}

using (var session = store.OpenSession())
{
var employee2 = session.Load<Employee>("employees/2");

// Register an event handler that will be called before any document is deleted during SaveChanges
session.Advanced.OnBeforeDelete += delegate (object sender, BeforeDeleteEventArgs args)
{
try
{
args.Session.Evict(employee2);
}
catch (InvalidOperationException e)
{
// An exception is thrown:
// "Cannot Evict entity during OnBeforeDelete..."
}
};

// Load employees/1 and mark it for deletion
var employee1 = session.Load<Employee>("employees/1");
session.Delete(employee1);

// SaveChanges triggers the OnBeforeDelete event
session.SaveChanges();
}

Syntax

void Evict<T>(T entity);
ParameterTypeDescription
TTType of the entity to evict
entityTInstance of the entity to evict from tracking