Visual Studio下C#代码中数据库插入语句重复执行问题
解决.NET测试Web应用重复插入数据库的问题
嘿,这个问题我之前调试测试项目时也踩过一模一样的坑!咱们先拆解可能的原因,再一步步解决:
常见原因分析
1. 插入代码被多次请求触发
最大概率的情况是:你把插入逻辑放在了每个请求都会走的管道环节(比如Startup.cs的Configure方法里),而浏览器刷新页面时会悄悄发起两次请求——一次是页面本身,另一次是自动请求站点的favicon.ico图标。这就导致每次刷新都会执行两次插入,产生完全重复的记录。
2. Startup代码被重复执行
如果是在调试模式下,ASP.NET Core的热重载机制或者应用启动时的某些初始化逻辑,可能会导致Startup里的代码被多次调用,进而重复执行插入操作。
解决方案
方案1:把插入逻辑改为应用启动时仅执行一次
别把测试插入代码放在请求处理管道里,而是绑定到应用启动完成的事件,确保只执行一次。可以在Program.cs里这样写:
var app = builder.Build(); // 先完成其他中间件配置(比如路由、静态文件等)... // 注册应用启动完成后的一次性执行逻辑 app.Lifetime.ApplicationStarted.Register(() => { using var scope = app.Services.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>(); // 插入前先检查数据是否已存在,从根源避免重复 var existingTestData = dbContext.YourTableName.FirstOrDefault(x => x.UniqueIdentifierField == "测试标识值"); if (existingTestData == null) { dbContext.YourTableName.Add(new YourEntity { // 填充你的测试字段 Name = "测试数据", CreateTime = DateTime.Now }); dbContext.SaveChanges(); } }); app.Run();
方案2:给数据库实体添加唯一约束
就算不小心触发了重复插入,也让数据库帮我们兜底,杜绝重复数据。在你的DbContext的OnModelCreating方法里配置唯一索引:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 给业务上唯一的字段添加约束,比如根据你的测试数据标识字段 modelBuilder.Entity<YourEntity>() .HasIndex(e => e.UniqueIdentifierField) .IsUnique(); }
这样重复插入时会直接抛出数据库异常,你能立刻发现哪里触发了重复执行,同时数据库里不会出现冗余数据。
方案3:排查请求触发的重复执行
如果你的插入逻辑必须在请求中执行(比如测试接口),那就在代码里判断请求路径,只允许特定路径触发插入:
// 在Configure方法的中间件里添加路径判断 app.Use(async (context, next) => { // 只在指定测试路径下执行插入 if (context.Request.Path.Equals("/test-insert", StringComparison.OrdinalIgnoreCase)) { using var scope = context.RequestServices.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>(); // 执行插入逻辑... } await next(); });
这样就算浏览器自动请求favicon,也不会触发插入操作了。
内容的提问来源于stack exchange,提问作者GrumpyWizard
相关产品推荐
相关产品推荐

