You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现用户批量加入组?现有逻辑优化需求

批量处理多组用户添加的实现方案

针对你已实现单组添加用户的逻辑,以下是批量处理多组用户添加的具体解决方案,兼顾性能与可读性:

1. 定义批量请求/响应模型

先构建支持批量操作的视图模型,明确输入输出结构:

// 复用你已有的单组添加请求模型
public class AddUserToGroupViewModel
{
    public int GroupId { get; set; }
    public List<string> UserId { get; set; }
}

// 批量请求模型:包含多组添加任务
public class BatchAddUserToGroupViewModel
{
    public List<AddUserToGroupViewModel> GroupUserRequests { get; set; }
}

// 批量返回结果模型:区分不同组的处理状态
public class BatchAddUserToGroupResponseViewModel
{
    public int GroupId { get; set; }
    public List<AddUserToGroupResponseViewModel> UserStatuses { get; set; }
}

2. 业务层实现批量处理逻辑

优化数据库查询次数,避免循环中重复调用DB,同时复用核心校验逻辑:

public async Task<List<BatchAddUserToGroupResponseViewModel>> BatchAddUserToGroupAsync(BatchAddUserToGroupViewModel batchModel)
{
    var batchResults = new List<BatchAddUserToGroupResponseViewModel>();
    if (batchModel?.GroupUserRequests == null || !batchModel.GroupUserRequests.Any())
    {
        return batchResults;
    }

    // 一次性查询所有待处理的有效组,减少多次DB调用
    var groupIds = batchModel.GroupUserRequests.Select(r => r.GroupId).Distinct();
    var validGroupIds = await this.lmsMasterRepository.GetListAsync<Group>(g => groupIds.Contains(g.Id) && !g.IsDeleted && g.IsActive)
        .ConfigureAwait(false)
        .Select(g => g.Id)
        .ToListAsync();

    // 一次性查询所有待处理的有效用户
    var allUserIds = batchModel.GroupUserRequests.SelectMany(r => r.UserId).Distinct();
    var validUserIds = await this.lmsMasterRepository.GetListAsync<User>(u => allUserIds.Contains(u.Id) && !u.IsDeleted && u.IsActive)
        .ConfigureAwait(false)
        .Select(u => u.Id)
        .ToListAsync();

    // 一次性查询所有组已存在的用户关系,替代多次调用GetAllUsersInGroup
    var existingUserGroups = await this.lmsMasterRepository.GetListAsync<UserGroup>(ug => validGroupIds.Contains(ug.GroupId))
        .ConfigureAwait(false)
        .GroupBy(ug => ug.GroupId)
        .ToDictionary(g => g.Key, g => g.Select(ug => ug.UserId).ToList());

    foreach (var groupRequest in batchModel.GroupUserRequests)
    {
        var groupResult = new BatchAddUserToGroupResponseViewModel
        {
            GroupId = groupRequest.GroupId,
            UserStatuses = new List<AddUserToGroupResponseViewModel>()
        };

        // 校验组是否有效
        if (!validGroupIds.Contains(groupRequest.GroupId))
        {
            groupResult.UserStatuses.Add(new AddUserToGroupResponseViewModel
            {
                Status = $"组 {groupRequest.GroupId} 无效或已删除"
            });
            batchResults.Add(groupResult);
            continue;
        }

        // 获取当前组已存在的用户列表
        existingUserGroups.TryGetValue(groupRequest.GroupId, out var existingUsersInGroup);
        existingUsersInGroup ??= new List<string>();

        // 筛选出符合条件的待添加用户:有效且未在组内
        var usersToAdd = groupRequest.UserId
            .Where(userId => validUserIds.Contains(userId) && !existingUsersInGroup.Contains(userId))
            .ToList();

        // 批量创建用户组关系
        if (usersToAdd.Any())
        {
            var userGroups = usersToAdd.Select(userId => new UserGroup
            {
                UserId = userId,
                GroupId = groupRequest.GroupId,
                CreatedDate = DateTime.UtcNow
            }).ToList();

            await this.lmsMasterRepository.CreateRangeAsync<UserGroup>(userGroups).ConfigureAwait(false);
        }

        // 整理添加失败的用户状态
        var failedUsers = groupRequest.UserId
            .Except(usersToAdd)
            .Select(userId => new AddUserToGroupResponseViewModel
            {
                UserId = userId,
                Status = validUserIds.Contains(userId) ? "用户已在组内" : "用户无效或已删除"
            });

        groupResult.UserStatuses.AddRange(failedUsers);
        batchResults.Add(groupResult);
    }

    // 统一提交所有变更,保障事务一致性
    await this.lmsMasterRepository.SaveAsync().ConfigureAwait(false);
    return batchResults;
}

3. 仓储层添加批量创建方法

为提升性能,给仓储层新增批量创建实体的方法,替代循环调用单个CreateAsync:

public async Task CreateRangeAsync<T>(List<T> entities) where T : class
{
    await this.MasterContext.Set<T>().AddRangeAsync(entities).ConfigureAwait(false);
}

核心优化说明

  • 减少DB往返:一次性查询所有待验证的组、用户及已有组关系,避免循环中重复访问数据库,大幅提升批量处理性能。
  • 事务保障:统一在最后调用SaveAsync,确保所有批量操作要么全部提交,要么全部回滚(基于DbContext的SaveChangesAsync天然支持事务)。
  • 清晰的结果反馈:区分每个组的处理状态,明确每个用户的失败原因,便于调用方排查问题。

如果你的需求是循环调用原有单组方法处理多组,直接遍历调用AddUserToGroupAsync即可,但上述方案的性能更优,适合大规模批量操作。

内容的提问来源于stack exchange,提问作者user19181303

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 02:10:57