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

Dapper.NET存储过程参数报错及Web API重复值处理需求咨询

问题2:重复值处理——删旧加新(禁止使用UPDATE)

先提个小建议:你现有代码里Task.Run(() => ...).Wait()这种写法会阻塞线程,在Web API里非常不推荐,容易导致性能瓶颈甚至死锁,咱们直接改成异步await的方式,同时加上事务保证操作的原子性(要么删和加都成功,要么都回滚)。

优化后的Web API代码

public async Task<CoCApiResponse> CreateVersion(CreateVersion versionObj)
{
    try
    {
        // 用await替代Wait(),非阻塞等待删除完成
        await versionRepository.DeleteVersions(objVersionCollection);
        // 异步创建新版本,直接获取结果
        var createdVersion = await versionRepository.CreateVersion(versionObj.version, lstVersion);
        
        return new CoCApiResponse 
        { 
            Success = true, 
            Data = createdVersion,
            Message = "重复版本已删除,新版本创建成功"
        };
    }
    catch (Exception ex)
    {
        return new CoCApiResponse 
        { 
            Success = false, 
            Message = $"操作失败:{ex.Message}"
        };
    }
}

Repository层实现建议

1. DeleteVersions(异步删除重复记录)

public async Task DeleteVersions(IEnumerable<Version> duplicateVersions)
{
    // 先提取要删除的版本标识(比如Id或者唯一键,根据你的重复判断规则来)
    var versionIds = duplicateVersions.Select(v => v.Id).ToList();
    
    using (var conn = new SqlConnection(_connectionString))
    {
        await conn.OpenAsync();
        // 执行删除,用Dapper的参数化查询避免SQL注入
        await conn.ExecuteAsync(@"
            DELETE FROM VersionTable 
            WHERE Id IN @VersionIds", 
            new { VersionIds = versionIds });
    }
}

2. CreateVersion(异步新增版本)

public async Task<Version> CreateVersion(string versionNumber, List<Version> versionData)
{
    // 这里假设你要插入单条,批量的话可以调整为ExecuteAsync
    var newVersion = versionData.First();
    newVersion.VersionNumber = versionNumber;
    
    using (var conn = new SqlConnection(_connectionString))
    {
        await conn.OpenAsync();
        // 插入后返回新创建的记录(包含自增Id等)
        return await conn.QuerySingleAsync<Version>(@"
            INSERT INTO VersionTable (VersionNumber, Description, CreatedDate)
            VALUES (@VersionNumber, @Description, GETDATE())
            SELECT Id, VersionNumber, Description, CreatedDate FROM VersionTable WHERE Id = SCOPE_IDENTITY()", 
            newVersion);
    }
}

关键注意事项:事务处理

因为删除和插入是两个独立操作,必须加事务保证原子性,否则可能出现删了旧记录但新记录插入失败的情况。调整下API和Repository的代码:

带事务的Web API

public async Task<CoCApiResponse> CreateVersion(CreateVersion versionObj)
{
    using (var conn = new SqlConnection(_connectionString))
    {
        await conn.OpenAsync();
        using (var transaction = conn.BeginTransaction())
        {
            try
            {
                // 把事务传递给Repository方法
                await versionRepository.DeleteVersions(objVersionCollection, transaction);
                var createdVersion = await versionRepository.CreateVersion(versionObj.version, lstVersion, transaction);
                
                transaction.Commit();
                return new CoCApiResponse { Success = true, Data = createdVersion };
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return new CoCApiResponse { Success = false, Message = ex.Message };
            }
        }
    }
}

支持事务的Repository方法

public async Task DeleteVersions(IEnumerable<Version> duplicateVersions, SqlTransaction transaction)
{
    var versionIds = duplicateVersions.Select(v => v.Id).ToList();
    // 执行时传入transaction参数
    await transaction.Connection.ExecuteAsync(@"
        DELETE FROM VersionTable 
        WHERE Id IN @VersionIds", 
        new { VersionIds = versionIds }, transaction: transaction);
}

public async Task<Version> CreateVersion(string versionNumber, List<Version> versionData, SqlTransaction transaction)
{
    var newVersion = versionData.First();
    newVersion.VersionNumber = versionNumber;
    
    return await transaction.Connection.QuerySingleAsync<Version>(@"
        INSERT INTO VersionTable (VersionNumber, Description, CreatedDate)
        VALUES (@VersionNumber, @Description, GETDATE())
        SELECT Id, VersionNumber, Description, CreatedDate FROM VersionTable WHERE Id = SCOPE_IDENTITY()", 
        newVersion, transaction: transaction);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:11:31