Skip to content

Getting a Collection of Instances

Sometimes you need every instance of a read model at once: a small report, an integrity check, a back-office export, or a diagnostic script. Chronicle answers this the same way it answers a single-instance read — from the materialized store when the read model has one, and by replaying events when it does not.

Either way the whole result set comes back in one call, so this is not the tool for hot list views or large data sets. Reach for materialized paging when the caller needs a window rather than everything.

var accounts = await eventStore.ReadModels.GetInstances<Account>();
foreach (var account in accounts)
{
Console.WriteLine($"{account.Name}: {account.Balance:C}");
}

Kotlin currently exposes single-instance read-model lookup only, so collection reads are not shown for that client.

For a materialized read model the kernel pages through the sink until it has read every stored instance, releases compliance-protected values, and returns them. For a passive read model it replays the events that feed the read model and returns the state that falls out, which is strongly consistent and proportional to the length of the history.

The read returns every instance. Apply language-native filtering afterwards, and keep that in-memory cost in mind.

var accounts = await eventStore.ReadModels.GetInstances<Account>();
var highValueAccounts = accounts
.Where(account => account.Balance > threshold)
.OrderByDescending(account => account.Balance)
.ToList();
Console.WriteLine($"Found {highValueAccounts.Count} high-value accounts.");

For large result sets, page the materialized read model or use a product-specific query model instead of reading everything and filtering afterward.

You can cap the number of events Chronicle processes. Because a cap only means something to a replay, passing one always replays — even for a materialized read model.

var orders = await eventStore.ReadModels.GetInstances<Order>(eventCount: 1_000);
Console.WriteLine($"Replayed {orders.Count()} orders from the capped history.");

This can make diagnostics faster, but it can also return incomplete state if the cap cuts off events that matter. Use an event-count cap for historical analysis, back-testing, or bounded diagnostics. Do not use it when the reader expects the current truth.

Read the whole collection when:

  • The read model population is small.
  • You are running an administrative or diagnostic task.
  • You are validating data derived from the event log.

Prefer paging or a database-native read when:

  • The page is user-facing and called frequently.
  • You need server-side filtering, sorting, or paging.
  • The read model has many instances.