使用Entity Framework Core循环保存数据时遇标识列插入错误
解决方案
错误原因
你循环复用了同一个TransactionData实例:第一次调用SaveChanges()后,EF会将数据库生成的InfoId(标识列值)赋值给这个实例。第二次循环时,你修改该实例的其他属性后再次添加到上下文,EF会认为你要插入一个带有已存在标识列值的记录,从而触发标识列插入限制的错误。SET IDENTITY_INSERT在这里无效,因为你根本不需要手动指定标识列值。
修复代码
把TransactionData的实例创建放到循环内部,每次循环都生成新的实体对象:
string[] request = { "test1", "test2", "test3" }; using (var IdContext = new ProofContext()) { foreach (var req in request) { // 每次循环创建新的实例 TransactionData TTD = new TransactionData(); TTD.Description = req; TTD.RecordId = 12; TTD.PaymentStatus = "Failed"; IdContext.TransactionData.Add(TTD); IdContext.SaveChanges(); } }
额外验证:确保模型配置正确
要让EF正确识别InfoId为数据库标识列,需要在模型上添加配置:
- 使用DataAnnotations:
public partial class TransactionData { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int InfoId { get; set; } // 标识列 public decimal UnitPrice { get; set; } public decimal ServiceFee { get; set; } public decimal TotalAmount { get; set; } public string Sku { get; set; } // 补充你代码中用到的Description、RecordId、PaymentStatus属性 }
- 或者使用Fluent API(在DbContext的
OnModelCreating方法中):
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<TransactionData>() .Property(t => t.InfoId) .IsRequired() .ValueGeneratedOnAdd(); // 标记为数据库生成的标识列 }
优化建议
如果数据量较大,建议将所有实体添加到上下文后,一次性调用SaveChanges(),减少数据库交互次数:
string[] request = { "test1", "test2", "test3" }; using (var IdContext = new ProofContext()) { foreach (var req in request) { TransactionData TTD = new TransactionData(); TTD.Description = req; TTD.RecordId = 12; TTD.PaymentStatus = "Failed"; IdContext.TransactionData.Add(TTD); } // 一次性保存所有记录 IdContext.SaveChanges(); }
内容的提问来源于stack exchange,提问作者cool
相关产品推荐
相关产品推荐

