Session: Subscribing to Session Events
-
Events allow users to perform custom actions in response to operations made in a
Document Store
or aSession
. -
An event is invoked when the selected action is executed on an entity, or querying is performed.
-
Subscribing to an event within a
Session
is valid only for this session.E.g., to invoke an event after SaveChanges() is called by this session only, use -
session.Advanced.OnAfterSaveChanges += OnAfterSaveChangesEvent;
-
Subscribing to an event at the
DocumentStore
level subscribes to this event in all subsequent sessions.E.g., to invoke an event after SaveChanges() is called by any subsequent session, use -
store.OnAfterSaveChanges += OnAfterSaveChangesEvent;
Read more about
DocumentStore
events here. -
In this Page:
OnBeforeStore
This event is invoked as a part of SaveChanges
but before it is actually sent to the server.
It should be defined with this signature:
private void OnBeforeStoreEvent(object sender, BeforeStoreEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeStoreEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being Stored, the document's metadata, and the document itself. |
The class BeforeStoreEventArgs
:
public class BeforeStoreEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
public IMetadataDictionary DocumentMetadata;
}
Example
Say we want to discontinue all of the products that are not in stock.
private void OnBeforeStoreEvent(object sender, BeforeStoreEventArgs args)
{
var product = args.Entity as Product;
if (product?.UnitsInStock == 0)
{
product.Discontinued = true;
}
}
After we subscribe to the event, every stored entity will invoke the method.
// Subscribe to the event
session.Advanced.OnBeforeStore += OnBeforeStoreEvent;
session.Store(new Product
{
Name = "RavenDB v3.5",
UnitsInStock = 0
});
session.Store(new Product
{
Name = "RavenDB v4.0",
UnitsInStock = 1000
});
session.SaveChanges(); // Here the method is invoked
OnBeforeDelete
This event is invoked by Delete(id)
or Delete(entity)
. It is only executed when SaveChanges()
is called, but before the commands are actually sent to the server.
It should be defined with this signature:
private void OnBeforeDeleteEvent(object sender, BeforeDeleteEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeDeleteEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being deleted, the document's metadata, and the document itself. |
The class BeforeDeleteEventArgs
:
public class BeforeDeleteEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
public IMetadataDictionary DocumentMetadata;
}
Example
To prevent anyone from deleting entities we can create a method as follows:
private void OnBeforeDeleteEvent(object sender, BeforeDeleteEventArgs args)
{
throw new NotSupportedException();
}
and subscribe it to the session:
// Subscribe to the event
session.Advanced.OnBeforeDelete += OnBeforeDeleteEvent;
var product = session.Load<Product>("products/1-A");
var product2 = session.Load<Product>("products/2-A");
// OnBeforeDelete is triggered whether you
// call Delete() on an entity or on its ID
session.Delete(product);
session.SaveChanges(); // NotSupportedException will be thrown
session.Delete("products/2-A");
session.SaveChanges(); // NotSupportedException will be thrown
OnAfterSaveChanges
This event is invoked after the SaveChanges
is returned.
It should be defined with this signature:
private void OnAfterSaveChangesEvent(object sender, AfterSaveChangesEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | AfterSaveChangesEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being deleted, and the document itself. |
The class AfterSaveChangesEventArgs
:
public class AfterSaveChangesEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
}
Example
If we want to log each entity that was saved, we can create a method as follows:
private void OnAfterSaveChangesEvent(object sender, AfterSaveChangesEventArgs args)
{
if (Log.IsInfoEnabled)
Log.Info($"Document '{args.DocumentId}' was saved.");
}
OnBeforeQuery
This event is invoked just before the query is sent to the server. It should be defined with this signature:
private void OnBeforeQueryEvent(object sender, BeforeQueryEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeQueryEventArgs |
args contains the session on which SaveChanges() has been called, and the query's query customizations. |
The class BeforeQueryEventArgs
:
public class BeforeQueryEventArgs
{
public InMemoryDocumentSessionOperations Session;
public IDocumentQueryCustomization queryCustomization;
}
Example I
If you want to disable caching of all query results, you can implement the method as follows:
private void OnBeforeQueryEvent(object sender, BeforeQueryEventArgs args)
{
args.QueryCustomization.NoCaching();
}
Example II
If you want each query to wait for non-stale results you can create an event as follows:
private void OnBeforeQueryEvent(object sender, BeforeQueryEventArgs args)
{
args.QueryCustomization.WaitForNonStaleResults(TimeSpan.FromSeconds(30));
}
OnBeforeConversionToDocument
This event is invoked before conversion of an entity to blittable JSON document. E.g. it's called when sending a document to a server.
It should be defined with this signature:
private void OnBeforeConversionToDocumentEvent(object sender, BeforeConversionToDocumentEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeConversionToDocumentEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being ConversionToDocumentd, and the document itself. |
The class BeforeConversionToDocumentEventArgs
:
public class BeforeConversionToDocumentEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
}
Example
private void OnBeforeConversionToDocument(object sender, BeforeConversionToDocumentEventArgs args)
{
if (args.Entity is Item item)
item.Before = true;
}
OnAfterConversionToDocument
This event is invoked after conversion of an entity to blittable JSON document.
It should be defined with this signature:
private void OnAfterConversionToDocumentEvent(object sender, AfterConversionToDocumentEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | AfterConversionToDocumentEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being ConversionToDocumentd, and the document itself. |
The class AfterConversionToDocumentEventArgs
:
public class AfterConversionToDocumentEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
}
Example
private void OnAfterConversionToDocument(object sender, AfterConversionToDocumentEventArgs args)
{
if (args.Entity is Item item)
{
if (args.Document.Modifications == null)
args.Document.Modifications = new DynamicJsonValue();
args.Document.Modifications["After"] = true;
args.Document = args.Session.Context.ReadObject(args.Document, args.Id);
item.After = true;
}
}
OnBeforeConversionToEntity
This event is invoked before conversion of a JSON document to an entity. E.g. it's called when loading a document.
It takes the argument BeforeConversionToEntityEventArgs
, that consists of a JSON document, its ID and type, and the session instance.
private void OnBeforeConversionToEntity(object sender, BeforeConversionToEntityEventArgs args)
{
var document = args.Document;
if (document.Modifications == null)
document.Modifications = new DynamicJsonValue();
document.Modifications["Before"] = true;
args.Document = args.Session.Context.ReadObject(document, args.Id);
}
OnAfterConversionToEntity
This event is invoked after conversion of a JSON document to an entity. It takes the argument AfterConversionToEntityEventArgs
, that consists of a JSON document, its ID, the session instance and a converted entity.
private void OnAfterConversionToEntity(object sender, AfterConversionToEntityEventArgs args)
{
if (args.Entity is Item item)
item.After = true;
}
OnSessionDisposing
This event is invoked by the disposal of a session, before the session is disposed of.
Keeping track of sessions disposal allows you, among other uses, to verify that sessions
that are no longer needed are disposed of.
private void OnSessionDisposingEvent(object sender, SessionDisposingEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session whose disposal triggered this event |
args | SessionDisposingEventArgs |
args contains the session that is disposed of. |
The class SessionDisposingEventArgs
:
public class SessionDisposingEventArgs : EventArgs
{
public InMemoryDocumentSessionOperations Session { get; }
}