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

如何正确使用Exists?用户注册重复邮箱仍被保存问题排查

问题修复方案

核心问题排查

你的代码中,重复邮箱用户仍被保存的可能原因如下:

  1. 角色判断限制:仅当用户角色为Role.USER时才触发邮箱唯一性检查,如果新用户角色不是USER,会直接跳过检查执行保存。
  2. 并发场景漏洞:代码层面的检查无法完全避免并发请求,两个请求同时通过邮箱检查后,会同时插入重复数据。
  3. Exists方法逻辑问题:如果Exists方法查询的是DbContext本地缓存而非数据库,可能无法正确检测到已存在的用户。

修复步骤

1. 扩大邮箱唯一性检查范围

将邮箱检查逻辑扩展到所有新用户(ID=0的用户),确保所有注册用户都强制邮箱唯一:

public override int Save(User entity, bool saveChanges = true, bool IgnoreValidation = false, bool checkConcurrency = true)
{
    try
    {
        bool sendMail = (entity.ID == 0);
        string clearPassword = null;

        // 新用户优先执行邮箱唯一性检查
        if (entity.ID == 0)
        {
            if (Exists(x => x.Email == entity.Email)) 
            {
                throw new EntityValidationException("系统中已存在使用该邮箱注册的用户");
            }
            // 密码处理逻辑
            clearPassword = string.IsNullOrEmpty(entity.Password) ? _passwordService.MakePassword() : entity.Password;
            entity.Password = _passwordService.EncryptSHA256(clearPassword);
        }

        int userSavedID = base.Save(entity, saveChanges);

        if (sendMail)
            _emailService.CreateNewCredentialEmail(entity, clearPassword);

        return userSavedID;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

2. 数据库层面添加唯一约束

这是防止重复数据的最可靠手段,即使代码层面出现漏洞,数据库会直接阻止插入:
在SQL数据库的Users表上,为Email字段添加唯一约束:

ALTER TABLE Users
ADD CONSTRAINT UQ_Users_Email UNIQUE (Email);

如果使用EF Core,也可以通过代码配置:

// 数据注解方式(在User实体类中)
[Index(nameof(Email), IsUnique = true)]
public string Email { get; set; }

// 或Fluent API(在DbContext的OnModelCreating方法中)
modelBuilder.Entity<User>()
    .HasIndex(u => u.Email)
    .IsUnique();

3. 验证Exists方法的实现

确保Exists方法是查询数据库而非本地缓存,比如EF环境下的正确实现:

public bool Exists(Expression<Func<User, bool>> predicate)
{
    // 使用DbSet.Any()查询数据库,而非Local.Any()
    return _dbContext.Users.Any(predicate);
}

额外说明

  • 移除了原代码中x.ID != entity.ID的条件,因为新用户ID为0,数据库中不存在ID=0的用户,该条件多余。
  • 数据库唯一约束会在插入重复数据时抛出异常,需要在上层代码中捕获并返回友好提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:33:40