.NET控制台应用EF Core SaveChanges插入标识列报错求助
解决EF Core插入SQL Server时的IDENTITY_INSERT错误
场景1:Id由数据库自动生成(常规情况)
问题根源是你的Release模型的Id属性(对应数据库Releases表的标识列)被显式赋值了,而SQL Server默认不允许给标识列插入显式值。
步骤1:配置模型的标识列
确保Release模型的Id被正确配置为数据库自动生成的标识列:
- 方法一:使用数据注解
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; public class Release { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 指定由数据库生成值 public int Id { get; set; } // 其他20个属性... }
- 方法二:使用Fluent API(在
ReleasesDbContext中添加配置)
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Release>() .Property(r => r.Id) .ValueGeneratedOnAdd(); // 等价于IDENTITY列 }
步骤2:避免给Id赋值
解析JSON时,确保不要将JSON中的Id值填充到模型的Id属性:
- 如果使用System.Text.Json,给
Id属性添加[JsonIgnore]注解:
[JsonIgnore] public int Id { get; set; }
- 如果使用Newtonsoft.Json,添加
[JsonIgnore](来自Newtonsoft.Json命名空间):
using Newtonsoft.Json; [JsonIgnore] public int Id { get; set; }
场景2:需要手动插入Id值(数据迁移等特殊情况)
如果确实要将自定义的Id值插入到标识列,需要临时开启IDENTITY_INSERT:
修改UpdateDatabase方法:
public static async Task UpdateDatabase() { Console.WriteLine("[INFO] Starting Database update..."); using (var _context = new ReleasesDbContext()) { Console.WriteLine("[WAIT] Database update in progress... Please hold!"); // 开启IDENTITY_INSERT _context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Releases ON"); foreach (var release in AllReleases) { _context.Releases.Add(release); } _context.SaveChanges(); // 关闭IDENTITY_INSERT _context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Releases OFF"); } Console.WriteLine("[DONE] Successfully applied database update(s)!"); }
注意:开启IDENTITY_INSERT后,插入时必须显式指定表的所有列(至少是标识列和非空列),不能依赖数据库的默认值生成。
内容的提问来源于stack exchange,提问作者rubber_duck
相关产品推荐
相关产品推荐

