Opening Sessions
Polecat uses sessions to manage document operations. Sessions provide a unit of work pattern -- changes are accumulated and flushed to the database in a single transaction when SaveChangesAsync() is called.
Session Types
Lightweight Session (Default)
No identity tracking. Each LoadAsync() call returns a new object instance:
await using var session = store.LightweightSession();Identity Map Session
Tracks loaded documents by ID. Repeated loads of the same document return the same instance:
await using var session = store.OpenSession(DocumentTracking.IdentityMap);Query Session (Read-Only)
For read-only operations. Cannot store or delete documents:
await using var session = store.QuerySession();Session Options
Configure sessions with SessionOptions:
await using var session = store.LightweightSession(new SessionOptions
{
// Multi-tenancy
TenantId = "my-tenant",
// Command timeout in seconds
Timeout = 30,
// Metadata tracking
CorrelationId = "request-123",
CausationId = "command-456",
LastModifiedBy = "user@example.com",
// Per-session listeners
Listeners = { new MySessionListener() }
});OpenSessionAsync
For scenarios requiring explicit transaction control, use OpenSessionAsync to eagerly open a connection and begin a transaction:
await using var session = await store.OpenSessionAsync(new SessionOptions
{
IsolationLevel = IsolationLevel.Serializable
});This is particularly useful for:
- Exclusive writing patterns (pessimistic locking)
- Custom isolation levels
- Ensuring a transaction is active before any operations
Unit of Work
Sessions accumulate pending operations:
await using var session = store.LightweightSession();
session.Store(new User { FirstName = "Alice" });
session.Store(new User { FirstName = "Bob" });
session.Delete<Order>(orderId);
// All operations execute in a single transaction
await session.SaveChangesAsync();Inspecting Pending Changes
var pending = session.PendingChanges;Ejecting Documents
Remove documents from pending changes without affecting the database:
// Eject a specific document
session.Eject(document);
// Eject all documents of a type
session.EjectAllOfType(typeof(User));
// Eject all pending changes
session.EjectAllPendingChanges();Session Listeners
Implement IDocumentSessionListener to hook into session lifecycle events:
public class AuditListener : IDocumentSessionListener
{
public Task BeforeSaveChangesAsync(IDocumentSession session, CancellationToken ct)
{
// Called before the transaction begins
return Task.CompletedTask;
}
public Task AfterCommitAsync(IDocumentSession session, CancellationToken ct)
{
// Called after the transaction commits
return Task.CompletedTask;
}
}Register listeners globally or per-session:
// Global (on all sessions)
opts.Listeners.Add(new AuditListener());
// Per-session
await using var session = store.LightweightSession(new SessionOptions
{
Listeners = { new AuditListener() }
});Request Counting
Track the number of database requests made by a session:
await using var session = store.LightweightSession();
await session.LoadAsync<User>(id);
Console.WriteLine(session.RequestCount); // 1
JasperFx provides formal support for Polecat and other Critter Stack libraries. Please check our