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

POST方法插入数据时如何仅通过代码实现Code字段唯一性校验

现有代码结构

模型类

public class SDN
{
    [Key]
    public int Id { get; set; }
    public int Codigo {get; set;}
    public string nit { get; set; }
    public string nombre { get; set; }
    public string telefono1 { get; set; }
    public string telefono2 { get; set; }
    public string direccion { get; set; }
    public string email { get; set; }
    public string codciudad { get; set; }
    public string codtipo { get; set; }
}

DTO类

public class SdnDTO
{
    public int Id { get; set; }
    public int Code { get; set; }
    [Required(ErrorMessage = "The field SDN Nit is required ")]
    public string nit { get; set; }
    [Required(ErrorMessage = "The field SDN Nombre is required ")]
    public string nombre { get; set; }
    public string telefono1 { get; set; }
    public string telefono2 { get; set; }
    public string direccion { get; set; }
    public string email { get; set; }
    public string codciudad { get; set; }
    public string codtipo { get; set; }
}

仓储层插入方法

public async Task<TEntity> Insert(TEntity entity)
{
    try
    {
        centralContext.Set<TEntity>().Add(entity);
        await centralContext.SaveChangesAsync();
        return entity;
    }
    catch (Exception ex)
    {
        throw ex;
    }         
}

服务层插入方法

public async Task<TEntity> Insert(TEntity entity)
{
    return await genericRepository.Insert(entity);
}

控制器插入接口

/// <summary>
/// 插入方法
/// </summary>
/// <param name="sdnDTO"></param>
/// <returns></returns>
[HttpPost]
public async Task<IHttpActionResult> Post(SdnDTO sdnDTO)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);
    try
    {
        var sdn = mapper.Map<SDN>(sdnDTO);
        sdn = await sdnService.Insert(sdn);
        return Ok(sdn);
    }
    catch (Exception ex) { return InternalServerError(ex); }
}

业务层实现Code唯一校验的方案

你需要校验的DTO的Code字段对应模型类的Codigo字段,无需修改数据库,仅调整业务代码的实现步骤如下:

  1. 先在仓储层新增通用存在性校验方法
    在你的泛型仓储类中添加如下方法,用于判断符合指定条件的记录是否存在:
using System.Linq.Expressions;

// 泛型仓储新增方法
public async Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate)
{
    return await centralContext.Set<TEntity>().AnyAsync(predicate);
}
  1. 服务层同步暴露该方法,泛型服务直接继承仓储方法即可
  2. 在插入逻辑中添加校验
    推荐将校验逻辑放在服务层,符合业务逻辑下沉的规范,如果你有SDN专属的服务类,可重写Insert方法:
// SDN专属服务类重写Insert方法
public async Task<SDN> Insert(SDN entity)
{
    // 校验Codigo是否已存在
    var isDuplicate = await ExistsAsync(s => s.Codigo == entity.Codigo);
    if (isDuplicate)
    {
        throw new InvalidOperationException("当前提交的Code值已存在,无法重复插入");
    }
    return await base.Insert(entity);
}

如果不想调整服务层,也可以直接在控制器中添加校验逻辑:

[HttpPost]
public async Task<IHttpActionResult> Post(SdnDTO sdnDTO)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);
    try
    {
        var sdn = mapper.Map<SDN>(sdnDTO);
        // 新增Code重复校验
        var codeExists = await sdnService.ExistsAsync<SDN>(s => s.Codigo == sdn.Codigo);
        if (codeExists)
        {
            return BadRequest("提交的Code值已存在,请勿重复提交");
        }
        sdn = await sdnService.Insert(sdn);
        return Ok(sdn);
    }
    catch (Exception ex) { return InternalServerError(ex); }
}

注意:该方案为业务层单实例校验,高并发场景下仍有极低概率出现重复插入,后续允许修改数据库时,建议给Codigo字段添加唯一索引做双层保障。另外请确认你的AutoMapper配置中已经正确配置了SdnDTO.Code到SDN.Codigo的映射关系,避免校验字段不匹配的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:06:04