Ncqrs recreate the complete ReadModel

343 Views Asked by At

Using Ncqrs, is there a way to replay every single event ever happened (all aggregate types) and feed these through my denormalizers in order to recreate the whole read model from scratch?

Edit:

I though it's be good to provide a more specific use case. I'm building this inside a ASP.NET MVC application and using Entity Framework (Code first) for working with the read models. In order to speed up development (and because I'm lazy), I want to use a database initializer that recreates the database schemas once any read model changes. Then using the initializer's seed method to repopulate them.

3

There are 3 best solutions below

0
On BEST ANSWER

What I ended up doing is the following. At the service startup, before any commands are being processed, if the read model has changed, I throw it away and recreate it from scratch by processing all past events in my denormalizers. This is done in the database initializer's seed method.

This was a trivial task using the MS SQL event storage as there was a method for retrieving all events. However, I'm not sure about other event storages.

0
On

We use a MsSqlServerEventStore, to replay all the events I implemented the following code:

var myEventBus = NcqrsEnvironment.Get<IEventBus>();
if (myEventBus == null) throw new Exception("EventBus is not found in NcqesEnvironment");
var myEventStore = NcqrsEnvironment.Get<IEventStore>() as MsSqlServerEventStore;
if (myEventStore == null) throw new Exception("MsSqlServerEventStore is not found in NcqesEnvironment");
var myEvents = myEventStore.GetEventsAfter(GetFirstEventIdFromEventStore(), int.MaxValue);
myEventBus.Publish(myEvents);

This will push all the events on the eventbus and the denormalizers will process all the events. The function GetFirstEventIdFromEventStore just queries the eventstore and returns the first Id from the eventstore (where SequentialId = 1)

1
On

There is unfortunately nothing built in to do this for you (though I haven't updated the version of ncqrs I use in quite a while so perhaps that's changed). It is also somewhat non-trivial to do it since it depends on exactly what you want to do.

The way I would do it (up to this point I have not had a need) would be to:

  • Call to the event store to get all relevant events

Depending on what you are doing this could be all events or just the events for one aggregate root, or a subset of events for one or more aggregate roots.

  • Re-create the read-model in memory from scratch (to save slow and unnecessary writing)

  • Store the re-created read-model in place of the existing one

  • Call to the event store one more time to get any events that may have been missed

  • Repeat until there are no new events being returned

One thing to note, if you are recreating the entire read-model database from scratch I would off-line the service temporarily or queue up new events until you finish.

Again there are different ways you could approach this problem, your architecture and scenarios will probably dictate how best to do it.