Repositories: Retrieve users for groups in batches to fix UserService.GetAllInGroup failing on too many users in a group (#20298)

* fix: Identified everywhere the bugs happen and implemented the InGroupOf() extension to successfully batch the SQL queries

* Added helper function in case this batching functionality is in future scopes

* Accidently deleted a groupIds.Any() check while adding BatchFetch helper function

* Removed helper function and instead utilising built in FetchByGroups extension method
This commit is contained in:
Piers Taylor
2025-10-07 15:09:24 +01:00
committed by GitHub
parent f5da0db977
commit e9ae3cf5db

View File

@@ -409,17 +409,14 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
Sql<ISqlContext> sql;
try
{
sql = SqlContext.Sql()
.Select<UserGroupDto>(x => x.Id, x => x.Key)
.From<UserGroupDto>()
.InnerJoin<User2UserGroupDto>().On<UserGroupDto, User2UserGroupDto>((left, right) => left.Id == right.UserGroupId)
.WhereIn<User2UserGroupDto>(x => x.UserId, userIds);
List<UserGroupDto>? userGroups = Database.Fetch<UserGroupDto>(sql);
groupKeys = userGroups.Select(x => x.Key).ToList();
groupKeys = Database.FetchByGroups<UserGroupDto, int>(userIds, Constants.Sql.MaxParameterCount, ints =>
{
return SqlContext.Sql()
.Select<UserGroupDto>(x => x.Id, x => x.Key)
.From<UserGroupDto>()
.InnerJoin<User2UserGroupDto>().On<UserGroupDto, User2UserGroupDto>((left, right) => left.Id == right.UserGroupId)
.WhereIn<User2UserGroupDto>(x => x.UserId, ints);
}).Select(x => x.Key).ToList();
}
catch (DbException)
{
@@ -433,12 +430,13 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
// get users2groups
sql = SqlContext.Sql()
.Select<User2UserGroupDto>()
.From<User2UserGroupDto>()
.WhereIn<User2UserGroupDto>(x => x.UserId, userIds);
List<User2UserGroupDto>? user2Groups = Database.Fetch<User2UserGroupDto>(sql);
List<User2UserGroupDto>? user2Groups = Database.FetchByGroups<User2UserGroupDto, int>(userIds, Constants.Sql.MaxParameterCount, ints =>
{
return SqlContext.Sql()
.Select<User2UserGroupDto>()
.From<User2UserGroupDto>()
.WhereIn<User2UserGroupDto>(x => x.UserId, ints);
}).ToList();
if (groupIds.Any() is false)
{
@@ -446,7 +444,6 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
groupIds = user2Groups.Select(x => x.UserGroupId).Distinct().ToList();
}
// get groups
// We wrap this in a try-catch, as this might throw errors when you try to login before having migrated your database
Dictionary<int, UserGroupDto> groups;
@@ -485,13 +482,13 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
.ToDictionary(x => x.Key, x => x);
// get start nodes
sql = SqlContext.Sql()
.Select<UserStartNodeDto>()
.From<UserStartNodeDto>()
.WhereIn<UserStartNodeDto>(x => x.UserId, userIds);
List<UserStartNodeDto>? startNodes = Database.Fetch<UserStartNodeDto>(sql);
List<UserStartNodeDto>? startNodes = Database.FetchByGroups<UserStartNodeDto, int>(userIds, Constants.Sql.MaxParameterCount, ints =>
{
return SqlContext.Sql()
.Select<UserStartNodeDto>()
.From<UserStartNodeDto>()
.WhereIn<UserStartNodeDto>(x => x.UserId, ints);
}).ToList();
// get groups2languages