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

.NET循环调用存储过程报错:已添加相同键StudentId

问题解决:An item with the same key has already been added. Key: StudentId

错误原因

LinkStudentToSubjectsAsync方法中,parameters字典在foreach循环外部初始化,每次循环都会向同一个字典添加StudentId和SubjectId键。第一次循环执行后,这两个键已存在于字典中,第二次循环执行parameters.Add时就会触发重复键异常。

修复方案

1. 调整参数字典初始化位置

将parameters字典的创建移至foreach循环内部,确保每次循环都使用全新的字典,避免重复添加键:

public async Task<bool> LinkStudentToSubjectsAsync(int studentId, int[] subjectIds)
{
    DeleteSubjectStudentLinks(studentId);
    StudentSubject? linkResult = null;

    foreach (var subjectId in subjectIds)
    {
        // 每次循环新建参数字典
        var parameters = new Dictionary<string, object>();
        parameters.Add(StoredProcedures.Params.StudentId, studentId);
        parameters.Add(StoredProcedures.Params.SubjectId, subjectId);
               
        linkResult = await _repository.ExecuteStoredProcAsync<StudentSubject>(StoredProcedures.LinkStudentSubjects, parameters);
    }

    return linkResult is not null;
}

2. 清理存储过程多余参数

存储过程中的@StudentSubjectID参数未被使用,且调用时未传入该参数,会导致调用异常,需删除该参数:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[LinkStudentSubjects] 
    @StudentID int,
    @SubjectID int
AS
BEGIN
    DECLARE @TableStudentSubjectID TABLE (ID int)

    -- 恢复并修正重复判断逻辑,避免重复插入关联记录
    IF NOT EXISTS (SELECT 1 FROM [dbo].[StudentSubjects]
                   WHERE StudentID = @StudentID AND SubjectID = @SubjectID)
    BEGIN
        INSERT INTO [dbo].[StudentSubjects] (StudentId, SubjectId)
        OUTPUT inserted.id INTO @TableStudentSubjectID(ID)
        VALUES (@StudentID, @SubjectID)
    END

    SELECT ID FROM @TableStudentSubjectID
END

3. 额外优化建议

  • 如果DeleteSubjectStudentLinks是数据库操作,建议改为异步方法DeleteSubjectStudentLinksAsync并使用await调用,避免阻塞线程。
  • 可以考虑批量插入代替循环调用存储过程(比如将subjectIds作为表值参数传入存储过程),提升执行性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 19:12:06