ClientController: split LoadClientAsync into per-collection subqueries
LoadClientAsync chains 9 .Include() calls on dbContext.Clients. On Postgres (and InMemory for some IdentityServer8 nav types), the resulting cartesian product trips the query shaper with IndexOutOfRangeException at IncludeCollection materialisation time. Bug reproduces in production on the Blog admin pages that load a Client by id. AsSplitQuery() rewrites the load as 9 separate SELECTs joined by client id, which sidesteps the cartesian explosion and any shaper ambiguity between Claims/Properties/ClientSecrets (which share Type/Value column names across some IdentityServer8 versions). Tests: - EditRedirectUris_GET_after_add_lists_both_uris: end-to-end reproducer that adds a second RedirectUri via POST then re-GETs the editor. Guards the fix on the integration path. - Bisect_*_alone: nine unit tests that exercise the same .SingleOrDefaultAsync(c => c.Id == id).Include(nav) on the InMemory provider, one nav at a time. Pinpointed three problematic navs (RedirectUris, AllowedScopes, AllowedGrantTypes) on InMemory; kept as a regression net for any future shaper regressions on the InMemory provider (not the Postgres path).
This commit is contained in:
parent
cb20b8a2d5
commit
b12c272df7
2 changed files with 230 additions and 0 deletions
|
|
@ -287,6 +287,7 @@ public partial class ClientController
|
|||
|
||||
private async Task<Client?> LoadClientAsync(int id)
|
||||
=> await dbContext.Clients
|
||||
.AsSplitQuery()
|
||||
.Include(c => c.RedirectUris)
|
||||
.Include(c => c.PostLogoutRedirectUris)
|
||||
.Include(c => c.AllowedScopes)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue