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

DotNet Core MVC更新字符串主键(Mfowcode)报错的解决方案咨询

解决方案

问题核心在于你当前使用修改后的新编码去查找原实体,而原实体的主键仍是旧值,自然无法定位。要解决主键更新的问题,核心是在请求中携带旧主键值来定位原实体,再更新为新值,同时需处理新主键的唯一性问题。


1. 修改命令类,添加旧主键字段

首先在UpdateOwnershipCommand中新增旧所有权编码字段,用于定位原实体:

public class UpdateOwnershipCommand
{
    // 旧编码:必须传入,用来定位要更新的原实体
    [Required]
    public string OldOwnershipCode { get; set; } = null!;

    // 新编码:用户修改后的目标编码
    [Required]
    public string OwnershipCode { get; set; } = null!;

    public string? OwnershipDescription { get; set; }
}

2. 更新命令处理逻辑

修改Handle方法,用旧编码定位实体,再更新为新值,同时增加新编码的唯一性校验:

public async Task<BaseResponse> Handle(UpdateOwnershipCommand request, CancellationToken cancellationToken)
{
    var response = new BaseResponse();
    try
    {
        // 用旧编码查找原实体
        var entity = await _context.Mfows.FindAsync(
            new object?[] { request.OldOwnershipCode }, 
            cancellationToken: cancellationToken) 
            ?? throw new NotFoundException(nameof(Mfow), request.OldOwnershipCode);

        // 如果新编码和旧编码不同,先检查新编码是否已存在
        if (!string.Equals(request.OwnershipCode, request.OldOwnershipCode, StringComparison.OrdinalIgnoreCase))
        {
            var isNewCodeExists = await _context.Mfows.AnyAsync(
                m => m.Mfowcode == request.OwnershipCode, 
                cancellationToken);
            if (isNewCodeExists)
            {
                throw new InvalidOperationException($"所有权编码 {request.OwnershipCode} 已存在");
            }
            // 更新主键字段
            entity.Mfowcode = request.OwnershipCode;
        }

        // 更新描述字段(按需处理空值)
        if (!string.IsNullOrEmpty(request.OwnershipDescription))
        {
            entity.Mfowdesc = request.OwnershipDescription;
        }

        await _context.SaveChangesAsync(cancellationToken);
        response.SetReturnSuccessStatus();
        response.Data = entity;
    }
    catch (NotFoundException ex)
    {
        response.SetReturnStatus(DanaPensiunConstants.ERROR_STATUS, ex.Message);
        response.Data = null;
        throw;
    }
    catch (InvalidOperationException ex)
    {
        response.SetReturnStatus(DanaPensiunConstants.ERROR_STATUS, ex.Message);
        response.Data = null;
        throw;
    }
    catch (Exception ex)
    {
        response.SetReturnStatus(DanaPensiunConstants.ERROR_STATUS, ex.Message);
        response.Data = null;
        throw new Exception(ex.Message);
    }
    return response;
}

3. 前端表单调整

在编辑页面中,将旧编码通过隐藏域自动传递(不要让用户修改旧编码),只允许用户修改新编码和描述字段,确保旧编码的准确性,避免人为输入错误导致定位失败。


补充说明

如果你的数据库或ORM配置限制直接修改主键,可考虑「删除原实体+插入新实体」的方案,但这种方式需要处理关联数据的迁移,风险较高,优先推荐上述带旧主键更新的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:17:05