From 68c2a0091ec4ee4d8b2d74aee191c8c91f3efcab Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 16 Aug 2023 16:18:12 +0800 Subject: [PATCH 1/4] Add separate methods to get role and usercount to improve performance --- .../Abp/Identity/IIdentityRoleRepository.cs | 13 ++++ .../Abp/Identity/IIdentityUserRepository.cs | 5 -- .../Volo/Abp/Identity/RoleWithUserCount.cs | 8 +- .../EfCoreIdentityRoleRepository.cs | 68 +++++++++++++++-- .../EfCoreIdentityUserRepository.cs | 19 ----- .../MongoDB/MongoIdentityRoleRepository.cs | 75 +++++++++++++++++-- .../MongoDB/MongoIdentityUserRepository.cs | 23 +----- .../Identity/IdentityRoleRepository_Tests.cs | 21 ++++++ .../Identity/IdentityUserRepository_Tests.cs | 10 --- 9 files changed, 170 insertions(+), 72 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs index 25b33936ba..f615de0933 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs @@ -14,6 +14,19 @@ public interface IIdentityRoleRepository : IBasicRepository CancellationToken cancellationToken = default ); + Task> GetAllListWithUserCountAsync( + CancellationToken cancellationToken = default + ); + + Task> GetListWithUserCountAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default + ); + Task> GetListAsync( string sorting = null, int maxResultCount = int.MaxValue, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs index 7aff7c5584..29d6af4e3f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs @@ -119,11 +119,6 @@ public interface IIdentityUserRepository : IBasicRepository CancellationToken cancellationToken = default ); - Task> GetCountAsync( - Guid[] roleIds, - CancellationToken cancellationToken = default - ); - Task FindByTenantIdAndUserNameAsync( [NotNull] string userName, Guid? tenantId, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RoleWithUserCount.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RoleWithUserCount.cs index 4030ce3fad..54b3f5e45e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RoleWithUserCount.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RoleWithUserCount.cs @@ -4,7 +4,13 @@ namespace Volo.Abp.Identity; public class RoleWithUserCount { - public Guid RoleId { get; set; } + public IdentityRole Role { get; set; } public long UserCount { get; set; } + + public RoleWithUserCount(IdentityRole role, long userCount) + { + Role = role; + UserCount = userCount; + } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs index c659dff653..340ad688de 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs @@ -28,6 +28,47 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } + public async Task> GetAllListWithUserCountAsync(CancellationToken cancellationToken = default) + { + var roles = await GetListInternalAsync(cancellationToken: cancellationToken); + var roleIds = roles.Select(x => x.Id).ToList(); + var userCount = await (await GetDbContextAsync()).Set() + .Where(userRole => roleIds.Contains(userRole.RoleId)) + .GroupBy(userRole => userRole.RoleId) + .Select(x => new + { + RoleId = x.Key, + Count = x.Count() + }) + .ToListAsync(GetCancellationToken(cancellationToken)); + + return roles.Select(role => new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); + } + + public async Task> GetListWithUserCountAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var roles = await GetListInternalAsync(sorting, maxResultCount, skipCount, filter, includeDetails, cancellationToken: cancellationToken); + + var roleIds = roles.Select(x => x.Id).ToList(); + var userCount = await (await GetDbContextAsync()).Set() + .Where(userRole => roleIds.Contains(userRole.RoleId)) + .GroupBy(userRole => userRole.RoleId) + .Select(x => new + { + RoleId = x.Key, + Count = x.Count() + }) + .ToListAsync(GetCancellationToken(cancellationToken)); + + return roles.Select(role => new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); + } + public virtual async Task> GetListAsync( string sorting = null, int maxResultCount = int.MaxValue, @@ -36,14 +77,7 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository x.Name.Contains(filter) || - x.NormalizedName.Contains(filter)) - .OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityRole.Name) : sorting) - .PageBy(skipCount, maxResultCount) - .ToListAsync(GetCancellationToken(cancellationToken)); + return await GetListInternalAsync(sorting , maxResultCount, skipCount, filter, includeDetails, cancellationToken); } public virtual async Task> GetListAsync( @@ -75,6 +109,24 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository> GetListInternalAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = true, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .IncludeDetails(includeDetails) + .WhereIf(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.NormalizedName.Contains(filter)) + .OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityRole.Name) : sorting) + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + [Obsolete("Use WithDetailsAsync")] public override IQueryable WithDetails() { diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs index 9aa6b133c5..8e6e9cba6c 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs @@ -263,25 +263,6 @@ public class EfCoreIdentityUserRepository : EfCoreRepository> GetCountAsync(Guid[] roleIds, CancellationToken cancellationToken = default) - { - var users = await (await GetDbSetAsync()) - .AsNoTracking() - .Where(user => user.Roles.Any(role => roleIds.Contains(role.RoleId))).IncludeDetails().ToListAsync(GetCancellationToken(cancellationToken)); - - var result = new List(); - foreach (var roleId in roleIds) - { - result.Add(new RoleWithUserCount - { - RoleId = roleId, - UserCount = users.Count(t => t.Roles.Any(role => role.RoleId == roleId)) - }); - } - - return result; - } - public virtual async Task> GetOrganizationUnitsAsync( Guid id, bool includeDetails = false, diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs index dfffe41116..83a987ae16 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs @@ -28,7 +28,25 @@ public class MongoIdentityRoleRepository : MongoDbRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public virtual async Task> GetListAsync( + public async Task> GetAllListWithUserCountAsync(CancellationToken cancellationToken = default) + { + var roles = await GetListInternalAsync(cancellationToken : cancellationToken); + var roleIds = roles.Select(x => x.Id).ToList(); + var userCount = await (await GetMongoQueryableAsync(cancellationToken)) + .Where(user => user.Roles.Any(role => roleIds.Contains(role.RoleId))) + .SelectMany(user => user.Roles) + .GroupBy(userRole => userRole.RoleId) + .Select(x => new + { + RoleId = x.Key, + Count = x.Count() + }) + .ToListAsync(GetCancellationToken(cancellationToken)); + + return roles.Select(role => new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); + } + + public async Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, @@ -36,14 +54,37 @@ public class MongoIdentityRoleRepository : MongoDbRepository x.Name.Contains(filter) || - x.NormalizedName.Contains(filter)) - .OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityRole.Name) : sorting) - .As>() - .PageBy>(skipCount, maxResultCount) + var roles = await GetListInternalAsync(sorting, maxResultCount, skipCount, filter, includeDetails, cancellationToken: cancellationToken); + var roleIds = roles.Select(x => x.Id).ToList(); + var userCount = await (await GetMongoQueryableAsync(cancellationToken)) + .Where(user => user.Roles.Any(role => roleIds.Contains(role.RoleId))) + .SelectMany(user => user.Roles) + .GroupBy(userRole => userRole.RoleId) + .Select(x => new + { + RoleId = x.Key, + Count = x.Count() + }) .ToListAsync(GetCancellationToken(cancellationToken)); + + return roles.Select(role => new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); + } + + public virtual async Task> GetListAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + return await GetListInternalAsync( + sorting, + maxResultCount, + skipCount, + filter, + includeDetails, + cancellationToken); } public virtual async Task> GetListAsync( @@ -75,4 +116,22 @@ public class MongoIdentityRoleRepository : MongoDbRepository>() .LongCountAsync(GetCancellationToken(cancellationToken)); } + + protected virtual async Task> GetListInternalAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = true, + CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(cancellationToken)) + .WhereIf(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.NormalizedName.Contains(filter)) + .OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityRole.Name) : sorting) + .As>() + .PageBy>(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } } diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs index b4a8d935fb..d478687f7b 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs @@ -268,26 +268,7 @@ public class MongoIdentityUserRepository : MongoDbRepository>(minModifitionTime != null, p => p.LastModificationTime >= minModifitionTime) .LongCountAsync(GetCancellationToken(cancellationToken)); } - - public async Task> GetCountAsync(Guid[] roleIds, CancellationToken cancellationToken = default) - { - var users = await (await GetMongoQueryableAsync(cancellationToken)) - .Where(user => user.Roles.Any(role => roleIds.Contains(role.RoleId))) - .ToListAsync(GetCancellationToken(cancellationToken)); - - var result = new List(); - foreach (var roleId in roleIds) - { - result.Add(new RoleWithUserCount - { - RoleId = roleId, - UserCount = users.Count(t => t.Roles.Any(role => role.RoleId == roleId)) - }); - } - - return result; - } - + public virtual async Task> GetUsersInOrganizationUnitAsync( Guid organizationUnitId, CancellationToken cancellationToken = default) @@ -318,7 +299,7 @@ public class MongoIdentityUserRepository : MongoDbRepository ou.Code.StartsWith(code)) .Select(ou => ou.Id) .ToListAsync(cancellationToken); - + return await (await GetMongoQueryableAsync(cancellationToken)) .Where(u => u.OrganizationUnits.Any(uou => organizationUnitIds.Contains(uou.OrganizationUnitId))) .ToListAsync(cancellationToken); diff --git a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs index 795ba45f42..41dcc8e6ba 100644 --- a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs @@ -66,4 +66,25 @@ public abstract class IdentityRoleRepository_Tests : AbpIdentity role.Claims.ShouldNotBeNull(); role.Claims.Any().ShouldBeTrue(); } + + [Fact] + public async Task GetAllListWithUserCountAsync() + { + var roles = await RoleRepository.GetAllListWithUserCountAsync(); + + roles.Count.ShouldBe(4); + roles.ShouldContain(r => r.Role.Name == "admin" && r.UserCount == 2); + roles.ShouldContain(r => r.Role.Name == "moderator" && r.UserCount == 1); + roles.ShouldContain(r => r.Role.Name == "supporter" && r.UserCount == 2); + roles.ShouldContain(r => r.Role.Name == "manager" && r.UserCount == 1); + } + + [Fact] + public async Task GetListWithUserCountAsync() + { + var roles = await RoleRepository.GetListWithUserCountAsync(filter: "admin"); + + roles.Count.ShouldBe(1); + roles.ShouldContain(r => r.Role.Name == "admin" && r.UserCount == 2); + } } diff --git a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs index 453917b08f..cb08fad60d 100644 --- a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs @@ -135,16 +135,6 @@ public abstract class IdentityUserRepository_Tests : AbpIdentity (await UserRepository.GetCountAsync("n")).ShouldBeGreaterThan(1); (await UserRepository.GetCountAsync("undefined-username")).ShouldBe(0); } - - [Fact] - public async Task GetCountAsync_With_RoleIds() - { - var roleWithUserCounts = await UserRepository.GetCountAsync(roleIds: new []{ TestData.RoleModeratorId, TestData.RoleSupporterId }); - - roleWithUserCounts.Count.ShouldBe(2); - roleWithUserCounts.ShouldContain(e => e.RoleId == TestData.RoleModeratorId && e.UserCount == 1); - roleWithUserCounts.ShouldContain(e => e.RoleId == TestData.RoleSupporterId && e.UserCount == 2); - } [Fact] public async Task GetUsersInOrganizationUnitAsync() From 426eefaa965e6a28c3a4d976d26e8e7ce7594e0b Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 16 Aug 2023 16:31:40 +0800 Subject: [PATCH 2/4] Remove GetAllListWithUserCountAsync method --- .../Abp/Identity/IIdentityRoleRepository.cs | 4 ---- .../EfCoreIdentityRoleRepository.cs | 17 ----------------- .../MongoDB/MongoIdentityRoleRepository.cs | 18 ------------------ .../Identity/IdentityRoleRepository_Tests.cs | 13 ++----------- 4 files changed, 2 insertions(+), 50 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs index f615de0933..8d32f8cb94 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs @@ -14,10 +14,6 @@ public interface IIdentityRoleRepository : IBasicRepository CancellationToken cancellationToken = default ); - Task> GetAllListWithUserCountAsync( - CancellationToken cancellationToken = default - ); - Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs index 340ad688de..c902330b4e 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs @@ -28,23 +28,6 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public async Task> GetAllListWithUserCountAsync(CancellationToken cancellationToken = default) - { - var roles = await GetListInternalAsync(cancellationToken: cancellationToken); - var roleIds = roles.Select(x => x.Id).ToList(); - var userCount = await (await GetDbContextAsync()).Set() - .Where(userRole => roleIds.Contains(userRole.RoleId)) - .GroupBy(userRole => userRole.RoleId) - .Select(x => new - { - RoleId = x.Key, - Count = x.Count() - }) - .ToListAsync(GetCancellationToken(cancellationToken)); - - return roles.Select(role => new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); - } - public async Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs index 83a987ae16..3d0c1b65c0 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs @@ -28,24 +28,6 @@ public class MongoIdentityRoleRepository : MongoDbRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public async Task> GetAllListWithUserCountAsync(CancellationToken cancellationToken = default) - { - var roles = await GetListInternalAsync(cancellationToken : cancellationToken); - var roleIds = roles.Select(x => x.Id).ToList(); - var userCount = await (await GetMongoQueryableAsync(cancellationToken)) - .Where(user => user.Roles.Any(role => roleIds.Contains(role.RoleId))) - .SelectMany(user => user.Roles) - .GroupBy(userRole => userRole.RoleId) - .Select(x => new - { - RoleId = x.Key, - Count = x.Count() - }) - .ToListAsync(GetCancellationToken(cancellationToken)); - - return roles.Select(role => new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); - } - public async Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, diff --git a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs index 41dcc8e6ba..c34e9ad56c 100644 --- a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityRoleRepository_Tests.cs @@ -68,9 +68,9 @@ public abstract class IdentityRoleRepository_Tests : AbpIdentity } [Fact] - public async Task GetAllListWithUserCountAsync() + public async Task GetListWithUserCountAsync() { - var roles = await RoleRepository.GetAllListWithUserCountAsync(); + var roles = await RoleRepository.GetListWithUserCountAsync(); roles.Count.ShouldBe(4); roles.ShouldContain(r => r.Role.Name == "admin" && r.UserCount == 2); @@ -78,13 +78,4 @@ public abstract class IdentityRoleRepository_Tests : AbpIdentity roles.ShouldContain(r => r.Role.Name == "supporter" && r.UserCount == 2); roles.ShouldContain(r => r.Role.Name == "manager" && r.UserCount == 1); } - - [Fact] - public async Task GetListWithUserCountAsync() - { - var roles = await RoleRepository.GetListWithUserCountAsync(filter: "admin"); - - roles.Count.ShouldBe(1); - roles.ShouldContain(r => r.Role.Name == "admin" && r.UserCount == 2); - } } From 8e092e6c527e683b5e7043c9172efd2e096f0ea7 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 16 Aug 2023 16:39:45 +0800 Subject: [PATCH 3/4] Rename RoleWithUserCount with IdentityRoleWithUserCount --- .../Volo/Abp/Identity/IIdentityRoleRepository.cs | 2 +- .../{RoleWithUserCount.cs => IdentityRoleWithUserCount.cs} | 4 ++-- .../EntityFrameworkCore/EfCoreIdentityRoleRepository.cs | 4 ++-- .../Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/{RoleWithUserCount.cs => IdentityRoleWithUserCount.cs} (64%) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs index 8d32f8cb94..d5f51ae71b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs @@ -14,7 +14,7 @@ public interface IIdentityRoleRepository : IBasicRepository CancellationToken cancellationToken = default ); - Task> GetListWithUserCountAsync( + Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RoleWithUserCount.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleWithUserCount.cs similarity index 64% rename from modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RoleWithUserCount.cs rename to modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleWithUserCount.cs index 54b3f5e45e..d706d4aa8e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RoleWithUserCount.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleWithUserCount.cs @@ -2,13 +2,13 @@ using System; namespace Volo.Abp.Identity; -public class RoleWithUserCount +public class IdentityRoleWithUserCount { public IdentityRole Role { get; set; } public long UserCount { get; set; } - public RoleWithUserCount(IdentityRole role, long userCount) + public IdentityRoleWithUserCount(IdentityRole role, long userCount) { Role = role; UserCount = userCount; diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs index c902330b4e..e51a7e923e 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs @@ -28,7 +28,7 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public async Task> GetListWithUserCountAsync( + public async Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, @@ -49,7 +49,7 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); + return roles.Select(role => new IdentityRoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); } public virtual async Task> GetListAsync( diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs index 3d0c1b65c0..4fef85e85c 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs @@ -28,7 +28,7 @@ public class MongoIdentityRoleRepository : MongoDbRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public async Task> GetListWithUserCountAsync( + public async Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, @@ -49,7 +49,7 @@ public class MongoIdentityRoleRepository : MongoDbRepository new RoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); + return roles.Select(role => new IdentityRoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList(); } public virtual async Task> GetListAsync( From 488b6816e5f0259ca67f781daf3a68743c088be5 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 16 Aug 2023 17:06:42 +0800 Subject: [PATCH 4/4] Add virtual keyword --- .../EntityFrameworkCore/EfCoreIdentityRoleRepository.cs | 2 +- .../Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs index e51a7e923e..57843adad0 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs @@ -28,7 +28,7 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public async Task> GetListWithUserCountAsync( + public virtual async Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs index 4fef85e85c..e94bacb92c 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs @@ -28,7 +28,7 @@ public class MongoIdentityRoleRepository : MongoDbRepository r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public async Task> GetListWithUserCountAsync( + public virtual async Task> GetListWithUserCountAsync( string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0,