diff --git a/SVSim.Database/Repositories/Viewer/IViewerRepository.cs b/SVSim.Database/Repositories/Viewer/IViewerRepository.cs index ea93d8ad..cea51a27 100644 --- a/SVSim.Database/Repositories/Viewer/IViewerRepository.cs +++ b/SVSim.Database/Repositories/Viewer/IViewerRepository.cs @@ -59,6 +59,14 @@ public interface IViewerRepository /// Task LoadForBattleXpGrantAsync(long viewerId, CancellationToken ct = default); + /// + /// Load a viewer with the joins 's Finish + /// needs: Classes (for the class-XP grant) + RankProgress (for the rank grant). Split-query + /// per project_ef_split_query to avoid the cartesian explosion when both nav + /// collections are populated on the same viewer. + /// + Task LoadForRankProgressAsync(long viewerId, CancellationToken ct = default); + /// Sets Viewer.GuildId to . No-op if the viewer does not exist. Task SetGuildIdAsync(long viewerId, int guildId, CancellationToken ct = default); diff --git a/SVSim.Database/Repositories/Viewer/ViewerRepository.cs b/SVSim.Database/Repositories/Viewer/ViewerRepository.cs index ed06edef..9fa22386 100644 --- a/SVSim.Database/Repositories/Viewer/ViewerRepository.cs +++ b/SVSim.Database/Repositories/Viewer/ViewerRepository.cs @@ -281,6 +281,16 @@ public class ViewerRepository : IViewerRepository .FirstOrDefaultAsync(v => v.Id == viewerId, ct); } + public Task LoadForRankProgressAsync(long viewerId, CancellationToken ct = default) + { + return _dbContext.Set() + .Include(v => v.Classes) + .ThenInclude(c => c.Class) + .Include(v => v.RankProgress) + .AsSplitQuery() + .FirstOrDefaultAsync(v => v.Id == viewerId, ct); + } + public async Task SetGuildIdAsync(long viewerId, int guildId, CancellationToken ct = default) { var viewer = await _dbContext.Set()