Fix LINQ translation in EnsureDefaultApplicationScopes

EF Core was throwing at startup with:

  System.InvalidOperationException: The LINQ expression
  '[ApiResourceScopeSpecification,...].Any(s => s.ResourceName == r.Name)'
  could not be translated.

The cause: Constants.ApiResourcesScopes is a static readonly C# array,
not an IQueryable, but it was used directly inside a Where clause on an
IQueryable<ApiResource>. EF tried to translate the closure over
Constants.ApiResourcesScopes into a SQL sub-query, which is not a
supported operation.

Materialise the wanted resource names into a HashSet before letting EF
see the Where — the collection is small (5 entries) so there's no
performance reason to push it down. After this fix,
EnsureDefaultApplicationScopes runs to completion at startup and
the seed actually has a chance of doing its job (assuming the rows
aren't already present).
This commit is contained in:
Paul Schneider 2026-06-25 23:20:43 +01:00
commit 571977f81b

View file

@ -640,8 +640,18 @@ public static class HostingExtensions
// Link each scope to its resource. We re-query both sets after
// the SaveChanges above so the newly inserted resources have
// their generated Ids.
//
// Note: Constants.ApiResourcesScopes is a static readonly array
// (not IQueryable), so we have to materialise the names into a
// local list before letting EF try to translate the Where into
// SQL — otherwise EF throws "The LINQ expression … could not be
// translated" at runtime.
var wantedResourceNames = Constants.ApiResourcesScopes
.Select(s => s.ResourceName)
.ToHashSet();
var resourceByName = apiResources
.Where(r => Constants.ApiResourcesScopes.Any(s => s.ResourceName == r.Name))
.Where(r => wantedResourceNames.Contains(r.Name))
.ToDictionary(r => r.Name);
foreach (var scopeSpec in Constants.ApiResourcesScopes)