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

为何无法实现软删除?需标记数据库角色状态并筛选有效记录

问题排查与修正方案

核心逻辑错误:软删除标记完全颠倒

你当前的标记逻辑和预期完全相反:

  • 默认IsDeleted = true意味着新创建的角色默认处于“已删除”状态
  • 执行“删除”操作时将IsDeleted设为false,反而让角色变成“未删除”状态
  • 获取角色时只查询IsDeleted == true的结果,导致新角色默认可见,“删除”后的角色反而被隐藏,完全违背软删除的预期逻辑

代码中的其他问题

  1. sDeleteCharacter方法返回结果未过滤状态
    更新角色后返回的列表没有过滤IsDeleted,导致返回结果包含被你标记为“删除”的角色,和GetAllCharacters的返回结果不一致,让你误以为软删除未生效。
  2. 查询待删除角色未过滤状态
    没有过滤IsDeleted,可能重复操作已被“删除”的角色,逻辑冗余。
  3. 未处理角色不存在的异常情况
    当目标角色不存在时,response.Data会为null,没有错误提示,前端可能出现异常。
  4. 异步查询使用同步方法
    最后查询角色列表用了同步的ToList(),应该用异步的ToListAsync()避免阻塞。

修正后的代码

1. 修正实体类的默认值

// 改为默认未删除,符合常规软删除逻辑
bool IsDeleted { get; set; } = false;

2. 修正软删除方法

public async Task<ServiceResponse<List<GetCharacterDto>>> sDeleteCharacter(int id)
{
    var response = new ServiceResponse<List<GetCharacterDto>>();
    try
    {
        // 仅查询当前用户未被删除的目标角色
        var character = await _context.Characters
            .FirstOrDefaultAsync(c => c.Id == id && c.User.Id == GetUserId() && !c.IsDeleted);
        
        if (character == null)
        {
            response.Success = false;
            response.Message = "角色不存在或已被删除";
            return response;
        }

        // 软删除:标记为已删除状态
        character.IsDeleted = true;
        await _context.SaveChangesAsync();

        // 返回当前用户所有未被删除的角色
        response.Data = await _context.Characters
            .Where(c => c.User.Id == GetUserId() && !c.IsDeleted)
            .Select(c => _mapper.Map<GetCharacterDto>(c))
            .ToListAsync();
    }
    catch (Exception ex)
    {
        response.Success = false;
        response.Message = ex.Message;
    }
    return response;
}

3. 修正获取所有角色方法

public async Task<ServiceResponse<List<GetCharacterDto>>> GetAllCharacters()
{
    var response = new ServiceResponse<List<GetCharacterDto>>();
    try
    {
        var dbCharacters = await _context.Characters
            .Where(c => c.User.Id == GetUserId() && !c.IsDeleted)
            .ToListAsync(); 
        
        response.Data = dbCharacters.Select(c => _mapper.Map<GetCharacterDto>(c)).ToList();
    }
    catch (Exception ex)
    {
        response.Success = false;
        response.Message = ex.Message;
    }
    return response;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:10:27