diff --git a/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs b/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs index d8338b470b..712cd25b2f 100644 --- a/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs @@ -233,17 +233,48 @@ public class CollectionRepository : Repository users) + public async Task UpdateUsersAsync(Guid id, IEnumerable requestedUsers) { using (var scope = ServiceScopeFactory.CreateScope()) { var dbContext = GetDatabaseContext(scope); - var procedure = new CollectionUserUpdateUsersQuery(id, users); - var updateData = await procedure.Update.BuildInMemory(dbContext); - dbContext.UpdateRange(updateData); - var insertData = await procedure.Insert.BuildInMemory(dbContext); - await dbContext.AddRangeAsync(insertData); - dbContext.RemoveRange(await procedure.Delete.Run(dbContext).ToListAsync()); + + var organizationId = await dbContext.Collections + .Where(c => c.Id == id) + .Select(c => c.OrganizationId) + .FirstOrDefaultAsync(); + + var existingCollectionUsers = await dbContext.CollectionUsers + .Where(cu => cu.CollectionId == id) + .ToListAsync(); + + foreach (var requestedUser in requestedUsers) + { + var existingCollectionUser = existingCollectionUsers.FirstOrDefault(cu => cu.OrganizationUserId == requestedUser.Id); + if (existingCollectionUser == null) + { + // This is a brand new entry + dbContext.CollectionUsers.Add(new CollectionUser + { + CollectionId = id, + OrganizationUserId = requestedUser.Id, + HidePasswords = requestedUser.HidePasswords, + ReadOnly = requestedUser.ReadOnly, + }); + continue; + } + + // It already exists, update it + existingCollectionUser.HidePasswords = requestedUser.HidePasswords; + existingCollectionUser.ReadOnly = requestedUser.ReadOnly; + dbContext.CollectionUsers.Update(existingCollectionUser); + } + + // Remove all existing ones that are no longer requested + var requestedUserIds = requestedUsers.Select(u => u.Id); + dbContext.CollectionUsers.RemoveRange(existingCollectionUsers.Where(cu => !requestedUserIds.Contains(cu.OrganizationUserId))); + await UserBumpAccountRevisionDateByCollectionId(id, organizationId); + await dbContext.SaveChangesAsync(); } } } diff --git a/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs b/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs index 3f6565d27b..3a40aa5760 100644 --- a/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs @@ -333,7 +333,7 @@ public class OrganizationUserRepository : Repository users) - { - Insert = new CollectionUserUpdateUsersInsertQuery(collectionId, users); - Update = new CollectionUserUpdateUsersUpdateQuery(collectionId, users); - Delete = new CollectionUserUpdateUsersDeleteQuery(collectionId, users); - } -} - -public class CollectionUserUpdateUsersInsertQuery : IQuery -{ - private readonly Guid _collectionId; - private readonly IEnumerable _users; - - public CollectionUserUpdateUsersInsertQuery(Guid collectionId, IEnumerable users) - { - _collectionId = collectionId; - _users = users; - } - - public IQueryable Run(DatabaseContext dbContext) - { - var orgId = dbContext.Collections.FirstOrDefault(c => c.Id == _collectionId)?.OrganizationId; - var organizationUserIds = _users.Select(u => u.Id); - var insertQuery = from ou in dbContext.OrganizationUsers - where - organizationUserIds.Contains(ou.Id) && - ou.OrganizationId == orgId && - !dbContext.CollectionUsers.Any( - x => x.CollectionId != _collectionId && x.OrganizationUserId == ou.Id) - select ou; - return insertQuery; - } - - public async Task> BuildInMemory(DatabaseContext dbContext) - { - var data = await Run(dbContext).ToListAsync(); - var collectionUsers = data.Select(x => new CollectionUser() - { - CollectionId = _collectionId, - OrganizationUserId = x.Id, - ReadOnly = _users.FirstOrDefault(u => u.Id.Equals(x.Id)).ReadOnly, - HidePasswords = _users.FirstOrDefault(u => u.Id.Equals(x.Id)).HidePasswords, - }); - return collectionUsers; - } -} - -public class CollectionUserUpdateUsersUpdateQuery : IQuery -{ - private readonly Guid _collectionId; - private readonly IEnumerable _users; - - public CollectionUserUpdateUsersUpdateQuery(Guid collectionId, IEnumerable users) - { - _collectionId = collectionId; - _users = users; - } - - public IQueryable Run(DatabaseContext dbContext) - { - var orgId = dbContext.Collections.FirstOrDefault(c => c.Id == _collectionId)?.OrganizationId; - var ids = _users.Select(x => x.Id); - var updateQuery = from target in dbContext.CollectionUsers - where target.CollectionId == _collectionId && - ids.Contains(target.OrganizationUserId) - select target; - return updateQuery; - } - - public async Task> BuildInMemory(DatabaseContext dbContext) - { - var data = await Run(dbContext).ToListAsync(); - var collectionUsers = data.Select(x => new CollectionUser - { - CollectionId = _collectionId, - OrganizationUserId = x.OrganizationUserId, - ReadOnly = _users.FirstOrDefault(u => u.Id.Equals(x.OrganizationUserId)).ReadOnly, - HidePasswords = _users.FirstOrDefault(u => u.Id.Equals(x.OrganizationUserId)).HidePasswords, - }); - return collectionUsers; - } -} - -public class CollectionUserUpdateUsersDeleteQuery : IQuery -{ - private readonly Guid _collectionId; - private readonly IEnumerable _users; - - public CollectionUserUpdateUsersDeleteQuery(Guid collectionId, IEnumerable users) - { - _collectionId = collectionId; - _users = users; - } - - public IQueryable Run(DatabaseContext dbContext) - { - var orgId = dbContext.Collections.FirstOrDefault(c => c.Id == _collectionId)?.OrganizationId; - var deleteQuery = from cu in dbContext.CollectionUsers - where !dbContext.Users.Any( - u => u.Id == cu.OrganizationUserId) - select cu; - return deleteQuery; - } -}