You need to enable JavaScript to run this app. C#结合SQL Server使用LinqToSql插入时报DuplicateKeyException错误
优惠活动
大模型
产品
解决方案
定价
更多

C#结合SQL Server使用LinqToSql插入时报DuplicateKeyException错误

DuplicateKeyException 异常排查方案

结合你提供的建表脚本、业务代码,可按以下概率从高到低定位问题:

  • LINQ to SQL 自增主键映射配置错误(最高发诱因)
    你的stagiaire表中id_stagiaire是设置了identity(1,1)的数据库自增主键,如果在DBML实体设计器中,没有将该字段的Auto Generated Value属性设置为True、同时将主键的Auto Sync设置为OnInsert,LINQ to SQL会默认该字段需要用户手动赋值。
    此时新建stagiaire实体时,id_stagiaire作为int类型默认值为0。第一次插入时,因为生成的SQL会显式带上id_stagiaire=0,数据库会抛出identity列不能显式插入的错误;但因为上下文会持续追踪失败的实体,这个主键为0的实体不会被从缓存中移除。第二次点击按钮插入新实体时,新实体的主键同样是默认值0,上下文检测到缓存中已经存在同主键的追踪对象,就会直接抛出「无法添加键已存在的实体」的异常,此时根本不会走到数据库提交环节。
  • 建表脚本的表存在性判断逻辑错误
    你所有的删表判断都写为if OBJECT_ID('tempdb..表名') is not null,该逻辑是在tempdb系统临时库中查找业务表,完全不会检测当前gestionStagiaire库中的表是否存在。
    这种写法会导致重复执行脚本时,判断永远为false、不会执行drop操作直接create,可能出现旧表结构残留、自增序列错乱、主键值和预期不一致的问题,最终引发主键冲突。
    正确的表存在判断写法为:if OBJECT_ID('dbo.stagiaire','U') is not null drop table stagiaire。
  • 全局复用DataContext导致的缓存冲突
    如果你的dc(DataContext实例)是在窗体类全局定义、长期复用的,会持续追踪所有操作过的实体对象,包括之前操作失败、未成功提交的实体。当你插入新实体时,只要实体的主键值和上下文缓存中已追踪的记录值一致,就会直接触发该异常,不会触发数据库层校验。
    推荐每次操作时按需实例化并释放DataContext,避免全局复用:
    // 每次数据库操作时新建实例,操作完成自动释放
    using (var dc = new DataClasses1DataContext())
    {
        stagiaire sr = new stagiaire();
        // 字段赋值逻辑
        dc.stagiaire.InsertOnSubmit(sr);
        dc.SubmitChanges();
    }
    
  • 关联实体映射错位
    你的ville表id_ville是无自增的手动赋值主键,代码中通过下拉框取id_ville值作为外键关联时,如果DBML中把外键关联的实体映射配置错位,可能导致上下文追踪的实体主键值和待插入实体的主键值混淆,触发键冲突异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 06:45:01