Browse Source

feat: add includeChildren parameter to GetMembersCountAsync for hierarchical member counting

pull/22498/head
maliming 11 months ago
parent
commit
c89946a70e
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 1
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs
  2. 32
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs
  3. 24
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs
  4. 7
      modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs

1
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs

@ -110,6 +110,7 @@ public interface IOrganizationUnitRepository : IBasicRepository<OrganizationUnit
Task<int> GetMembersCountAsync(
OrganizationUnit organizationUnit,
string filter = null,
bool includeChildren = false,
CancellationToken cancellationToken = default
);

32
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs

@ -231,9 +231,10 @@ public class EfCoreOrganizationUnitRepository
public virtual async Task<int> GetMembersCountAsync(
OrganizationUnit organizationUnit,
string filter = null,
bool includeChildren = false,
CancellationToken cancellationToken = default)
{
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter, includeChildren);
return await query.CountAsync(GetCancellationToken(cancellationToken));
}
@ -324,14 +325,33 @@ public class EfCoreOrganizationUnitRepository
dbContext.Set<IdentityUserOrganizationUnit>().RemoveRange(ouMembersQuery);
}
protected virtual async Task<IQueryable<IdentityUser>> CreateGetMembersFilteredQueryAsync(OrganizationUnit organizationUnit, string filter = null)
protected virtual async Task<IQueryable<IdentityUser>> CreateGetMembersFilteredQueryAsync(
OrganizationUnit organizationUnit,
string filter = null,
bool includeChildren = false)
{
var dbContext = await GetDbContextAsync();
var query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join user in dbContext.Users on userOu.UserId equals user.Id
where userOu.OrganizationUnitId == organizationUnit.Id
select user;
IQueryable<IdentityUser> query;
if (includeChildren)
{
var childrenIds = await (await GetDbSetAsync())
.Where(ou => ou.Code.StartsWith(organizationUnit.Code))
.Select(x => x.Id)
.ToListAsync();
query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join user in dbContext.Users on userOu.UserId equals user.Id
where childrenIds.Contains(userOu.OrganizationUnitId)
select user;
}
else
{
query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join user in dbContext.Users on userOu.UserId equals user.Id
where userOu.OrganizationUnitId == organizationUnit.Id
select user;
}
if (!filter.IsNullOrWhiteSpace())
{

24
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs

@ -193,7 +193,7 @@ public class MongoOrganizationUnitRepository
CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter, cancellationToken);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter, false, cancellationToken);
return await query
.OrderBy(sorting.IsNullOrEmpty() ? nameof(IdentityUser.UserName) : sorting)
.As<IMongoQueryable<IdentityUser>>()
@ -212,10 +212,11 @@ public class MongoOrganizationUnitRepository
public virtual async Task<int> GetMembersCountAsync(
OrganizationUnit organizationUnit,
string filter = null,
bool includeChildren = false,
CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter, cancellationToken);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter, includeChildren, cancellationToken);
return await query.CountAsync(cancellationToken);
}
@ -286,8 +287,27 @@ public class MongoOrganizationUnitRepository
protected virtual async Task<IMongoQueryable<IdentityUser>> CreateGetMembersFilteredQueryAsync(
OrganizationUnit organizationUnit,
string filter = null,
bool includeChildren = false,
CancellationToken cancellationToken = default)
{
if (includeChildren)
{
var childrenIds = await (await GetMongoQueryableAsync(cancellationToken))
.Where(ou => ou.Code.StartsWith(organizationUnit.Code))
.Select(ou => ou.Id)
.ToListAsync(GetCancellationToken(cancellationToken));
return (await GetMongoQueryableAsync<IdentityUser>(cancellationToken))
.Where(u => u.OrganizationUnits.Any(uou => childrenIds.Contains(uou.OrganizationUnitId)))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(
!filter.IsNullOrWhiteSpace(),
u =>
u.UserName.Contains(filter) ||
u.Email.Contains(filter) ||
(u.PhoneNumber != null && u.PhoneNumber.Contains(filter))
);
}
return (await GetMongoQueryableAsync<IdentityUser>(cancellationToken))
.Where(u => u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(

7
modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs

@ -267,6 +267,10 @@ public abstract class OrganizationUnitRepository_Tests<TStartupModule> : AbpIden
var usersCount = await _organizationUnitRepository.GetMembersCountAsync(ou);
usersCount.ShouldBeGreaterThan(1);
usersCount = await _organizationUnitRepository.GetMembersCountAsync(ou, includeChildren: true);
usersCount.ShouldBeGreaterThanOrEqualTo(2);
}
[Fact]
@ -301,6 +305,9 @@ public abstract class OrganizationUnitRepository_Tests<TStartupModule> : AbpIden
await _organizationUnitRepository.RemoveAllMembersAsync(ou);
var newCount = await _organizationUnitRepository.GetMembersCountAsync(ou);
newCount.ShouldBe(0);
newCount = await _organizationUnitRepository.GetMembersCountAsync(ou, includeChildren: true);
newCount.ShouldBe(0);
}
[Fact]

Loading…
Cancel
Save