Querying
The query builder
Section titled “The query builder”ICalendarStore.Query() returns a CalendarEventQuery — a small fluent builder. Nothing runs
until you call a terminal method (ToListAsync, FirstOrDefaultAsync, CountAsync), and the native
calendar read is performed off the calling thread, so it is safe to await straight from the UI
thread.
var upcoming = await store .Query() .ForCalendar(calId) .Between(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(7)) .OrderBy(CalendarEventSortField.Start) .ToListAsync(ct);Two things are pushed down to the native fetch — the calendar id and the start/end window — because those map directly onto the platform event query. Everything else (title/location/description text, attendee filters, availability, sorting, paging) is applied to the fetched events.
Native fetch hints
Section titled “Native fetch hints”| Builder call | Effect |
|---|---|
ForCalendar(id) |
Restricts the fetch to that calendar. null (the default) queries all of them. |
From(date) |
Sets the window lower bound. |
To(date) |
Sets the window upper bound. |
Between(from, to) |
Both at once. Throws if to precedes from. |
In-memory filters
Section titled “In-memory filters”// Free-text title filter (case-insensitive)var standups = await store.Query() .From(DateTimeOffset.Now.AddDays(-30)) .TitleContains("standup") .ToListAsync();
// Any predicate you like — multiple calls are ANDedvar withAlice = await store.Query() .Where(e => e.Attendees.Any(a => a.Email == "alice@example.com")) .Where(e => e.Availability == EventAvailability.Busy) .ToListAsync();Sorting and paging
Section titled “Sorting and paging”var page = await store.Query() .Between(from, to) .OrderBy(CalendarEventSortField.Start) .ThenBy(CalendarEventSortField.Title) .Skip(0) .Take(20) .ToListAsync();CalendarEventSortField is Start, End, or Title. OrderBy replaces any previous sort; ThenBy
adds a secondary one and throws if no OrderBy precedes it. Both take a descending flag.
Terminal methods
Section titled “Terminal methods”| Method | Returns |
|---|---|
ToListAsync(ct) |
IReadOnlyList<CalendarEvent> |
FirstOrDefaultAsync(ct) |
CalendarEvent? |
CountAsync(ct) |
int |
var count = await store.Query() .Between(from, to) .Where(e => e.Availability == EventAvailability.Busy) .CountAsync();Direct fetch
Section titled “Direct fetch”When you already know the window and need no extra filtering, GetEvents is the direct equivalent of
the native fetch:
var events = await store.GetEvents( calendarId: calId, start: DateTimeOffset.Now, end: DateTimeOffset.Now.AddMonths(1));

