Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Task<List<IdentityLinkUser>> GetListAsync(
List<IdentityLinkUserInfo> excludes = null,
CancellationToken cancellationToken = default);

Task<List<IdentityLinkUser>> GetListAsync(
int batchSize,
CancellationToken cancellationToken = default);

Task DeleteAsync(
IdentityLinkUserInfo linkUserInfo,
CancellationToken cancellationToken = default);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;
Expand All @@ -23,52 +23,64 @@ public IdentityLinkUserManager(IIdentityLinkUserRepository identityLinkUserRepos
CurrentTenant = currentTenant;
}

public async Task<List<IdentityLinkUser>> GetListAsync(IdentityLinkUserInfo linkUserInfo, bool includeIndirect = false, CancellationToken cancellationToken = default)
public async Task<List<IdentityLinkUser>> GetListAsync(IdentityLinkUserInfo linkUserInfo, bool includeIndirect = false, int batchSize = 100 * 100, CancellationToken cancellationToken = default)
{
using (CurrentTenant.Change(null))
{
var users = await IdentityLinkUserRepository.GetListAsync(linkUserInfo, cancellationToken: cancellationToken);
if (includeIndirect == false)
if (!includeIndirect)
{
return users;
}

var userInfos = new List<IdentityLinkUserInfo>()
{
linkUserInfo
};
var allUsers = await IdentityLinkUserRepository.GetListAsync(batchSize ,cancellationToken: cancellationToken);
return await GetAllRelatedLinksAsync(allUsers, linkUserInfo);
}
}

protected virtual Task<List<IdentityLinkUser>> GetAllRelatedLinksAsync(List<IdentityLinkUser> allUsers, IdentityLinkUserInfo userInfo)
{
var visited = new HashSet<(Guid, Guid?)>();
var result = new List<IdentityLinkUser>();
var queue = new Queue<(Guid, Guid?)>();

queue.Enqueue((userInfo.UserId, userInfo.TenantId));
visited.Add((userInfo.UserId, userInfo.TenantId));

while (queue.Count > 0)
{
var (currentUserId, currentTenantId) = queue.Dequeue();

var allUsers = new List<IdentityLinkUser>();
allUsers.AddRange(users);
var relatedLinks = allUsers.Where(x =>
(x.SourceUserId == currentUserId && x.SourceTenantId == currentTenantId) ||
(x.TargetUserId == currentUserId && x.TargetTenantId == currentTenantId)
).ToList();

do
foreach (var link in relatedLinks)
{
var nextUsers = new List<IdentityLinkUserInfo>();
foreach (var user in users)
var node1 = (link.SourceUserId, link.SourceTenantId);
var node2 = (link.TargetUserId, link.TargetTenantId);

if (!result.Contains(link))
{
if (userInfos.Any(x => x.TenantId != user.SourceTenantId || x.UserId != user.SourceUserId))
{
nextUsers.Add(new IdentityLinkUserInfo(user.SourceUserId, user.SourceTenantId));
}

if (userInfos.Any(x => x.TenantId != user.TargetTenantId || x.UserId != user.TargetUserId))
{
nextUsers.Add(new IdentityLinkUserInfo(user.TargetUserId, user.TargetTenantId));
}
result.Add(link);
}

users = new List<IdentityLinkUser>();
foreach (var next in nextUsers)
if (!visited.Contains(node1))
{
users.AddRange(await IdentityLinkUserRepository.GetListAsync(next, userInfos, cancellationToken));
queue.Enqueue(node1);
visited.Add(node1);
}

userInfos.AddRange(nextUsers);
allUsers.AddRange(users);
} while (users.Any());

return allUsers;
if (!visited.Contains(node2))
{
queue.Enqueue(node2);
visited.Add(node2);
}
}
}

return Task.FromResult(result);
}

public virtual async Task LinkAsync(IdentityLinkUserInfo sourceLinkUser, IdentityLinkUserInfo targetLinkUser, CancellationToken cancellationToken = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@ public virtual async Task<List<IdentityLinkUser>> GetListAsync(IdentityLinkUserI
return await query.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken));
}

public virtual async Task<List<IdentityLinkUser>> GetListAsync(int batchSize, CancellationToken cancellationToken = default)
{
var result = new List<IdentityLinkUser>();

var total = await (await GetDbSetAsync()).LongCountAsync(cancellationToken);
var pages = (int)Math.Ceiling(total / (double)batchSize);

for (var page = 0; page < pages; page++)
{
var batch = await (await GetDbSetAsync())
.AsNoTracking()
.OrderBy(x => x.Id)
.Skip(page * batchSize)
.Take(batchSize)
.ToListAsync(cancellationToken);

result.AddRange(batch);
}

return result;
}

public virtual async Task DeleteAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default)
{
var linkUsers = await (await GetDbSetAsync()).AsNoTracking().Where(x =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ public virtual async Task<List<IdentityLinkUser>> GetListAsync(IdentityLinkUserI
return await query.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken));
}

public virtual async Task<List<IdentityLinkUser>> GetListAsync(int batchSize, CancellationToken cancellationToken = default)
{
var result = new List<IdentityLinkUser>();

var total = await (await GetQueryableAsync(cancellationToken)).LongCountAsync(cancellationToken);
var pages = (int)Math.Ceiling(total / (double)batchSize);

for (var page = 0; page < pages; page++)
{
var batch = await (await GetQueryableAsync(cancellationToken))
.OrderBy(x => x.Id)
.Skip(page * batchSize)
.Take(batchSize)
.ToListAsync(cancellationToken);

result.AddRange(batch);
}

return result;
}

public virtual async Task DeleteAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default)
{
var linkUsers = await (await GetQueryableAsync(cancellationToken)).Where(x =>
Expand Down
Loading