.NET 4.8 WinForms添加新元素时EF6抛出DbUpdateConcurrencyException
批量添加EF6数据时触发DbUpdateConcurrencyException异常的排查方案
问题背景
基于.NET 4.8的WinForms应用,使用Entity Framework 6操作数据。调用context.SaveChanges();批量添加factPeriods集合时,抛出DbUpdateConcurrencyException异常。
相关代码片段
数据操作代码
using (FactContext context = new FactContext(connection.ConnectionString)) { context.Bastion_FactPeriods.AddRange(factPeriods); context.SaveChanges(); }
实体类定义
[Table(nameof(Bastion_FactPeriods))] public partial class Bastion_FactPeriods { [Key] [Column(Order = 0)] public long ID { get; set; } [Column(Order = 1)] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int ID_Branch { get; set; } [Column(Order = 2)] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int ID_Area { get; set; } public int TN { get; set; } public DateTime Time_begin { get; set; } public DateTime Time_end { get; set; } public int Time_value { get; set; } public DateTime? Used { get; set; } public bool? OnlyEntrance { get; set; } }
数据库表结构说明
表Bastion_FactPeriods的字段类型、主键设置等信息(原展示为DBeaver中的表结构)。
核心原因分析
- 主键冲突:实体的复合主键(ID、ID_Branch、ID_Area)在
factPeriods集合中存在重复,或已存在于数据库中,EF6尝试插入时触发数据库主键约束,被转换为并发异常。 - 实体与数据库主键配置不匹配:实体类标记了三个字段为复合主键,但数据库表实际仅将ID设为主键,导致EF6对数据存在性的判断逻辑错误。
- 字段生成规则不匹配:
ID_Branch和ID_Area设置了DatabaseGeneratedOption.None(应用提供值),但数据库中这两个字段可能是自动生成或有默认值,EF6插入后发现数据库值与预期不符,触发并发检查异常。 - 批量数据重复:集合内存在相同的复合主键组合,EF6 AddRange未提前检测,数据库插入时报错被封装为并发异常。
解决步骤
- 检查
factPeriods中每个元素的ID+ID_Branch+ID_Area组合是否唯一,且未在数据库中存在。 - 对比实体类的主键配置与数据库表的实际主键设置,确保二者完全一致。
- 验证
ID_Branch和ID_Area的DatabaseGenerated配置是否与数据库字段的生成规则匹配(若数据库自动生成则改为Identity,若应用提供则保持None)。 - 尝试单条数据插入,确认是否仍触发异常,逐步定位问题数据。
内容的提问来源于stack exchange,提问作者Skrillim
相关产品推荐
相关产品推荐

