perf(ui): batch event-list snapshot loads + push distinct dimensions to DB (HIGH)

* EventBrowsingService.BuildListAsync issued one snapshot query per event
  on every page render — N+1 against SQLite, with each round-trip hauling
  the full bet graph via Include(Bets). Replaced with a single
  ISnapshotRepository.ListByEventsAsync batch.
* ListKnownSportCodesAsync / ListKnownCountryCodesAsync used to materialise
  every Event row to compute Distinct() in memory. Pushed to EF projection
  via two new IEventRepository methods (ListDistinctSportCodesAsync,
  ListDistinctCountryCodesAsync) implemented as
  .Select(...).Distinct().ToListAsync — single SELECT DISTINCT.
This commit is contained in:
2026-05-09 15:29:05 +03:00
parent 286b55986b
commit 857d456b95
3 changed files with 50 additions and 22 deletions
@@ -12,4 +12,16 @@ public interface IEventRepository : IRepository<EventId, Event>
Task<IReadOnlyList<Event>> ListByDateRangeAsync(DateRange range, CancellationToken ct = default);
Task<IReadOnlyList<Event>> ListBySportAsync(SportCode sport, CancellationToken ct = default);
/// <summary>
/// Distinct sport codes across the events table. Projects in the database
/// rather than materialising every <see cref="Event"/> on the client.
/// </summary>
Task<IReadOnlyList<int>> ListDistinctSportCodesAsync(CancellationToken ct = default);
/// <summary>
/// Distinct ISO-2 country codes across the events table. Projects in the
/// database rather than materialising every <see cref="Event"/>.
/// </summary>
Task<IReadOnlyList<string>> ListDistinctCountryCodesAsync(CancellationToken ct = default);
}