EF Core项目切换为Swagger API后,增删改操作无法同步到数据库(查询功能正常)
EF Core项目切换为Swagger API后,增删改操作无法同步到数据库(查询功能正常)
兄弟,我刚看到你的问题,简直和我当初第一次把Razor Pages项目改成API时踩的坑一模一样!查询能正常返回数据,但增删改返回成功状态码,数据库却纹丝不动,控制台还打印了执行日志,这种情况十有八九是EF Core的数据库上下文更改没提交到数据库,咱们一步步排查:
最可能的原因:仓储层没调用SaveChanges()
你现在的控制器里调用了_userRepo.Delete(id)和_userRepo.Add(newUser),但大概率你的仓储(Repository)实现里只做了“标记实体状态”的操作,却没告诉EF Core把这些更改同步到数据库——也就是没调用DbContext.SaveChanges()或者异步版本的SaveChangesAsync()。
举个例子,假设你原来的仓储Delete方法是这样的:
// 错误的实现:只移除实体但不提交更改 public void Delete(int id) { var user = _context.Users.Find(id); if (user != null) { _context.Users.Remove(user); // 只是标记为待删除,还没写到数据库 } }
那你需要给它加上提交更改的代码:
// 正确的实现:标记后提交更改 public void Delete(int id) { var user = _context.Users.Find(id); if (user != null) { _context.Users.Remove(user); _context.SaveChanges(); // 关键!把更改同步到数据库 } }
同理,Add方法也需要加上SaveChanges():
public void Add(User user) { _context.Users.Add(user); _context.SaveChanges(); // 提交新增的实体到数据库 }
次要可能:查询用了无跟踪导致实体状态未被跟踪
如果你的_userRepo.Get(id)方法用了AsNoTracking()(无跟踪查询),比如:
public User Get(int id) { return _context.Users.AsNoTracking().FirstOrDefault(u => u.Id == id); }
那你拿到的user对象是EF Core不跟踪的,这时候调用_context.Users.Remove(user)不会生效,因为EF Core不知道这个实体的存在。
解决办法有两种:
- 把查询改成跟踪查询,比如用
Find方法(默认跟踪):public User Get(int id) { return _context.Users.Find(id); // Find方法会自动跟踪实体 } - 如果必须用无跟踪查询,删除前先把实体附加到上下文:
public void Delete(int id) { var user = _userRepo.Get(id); if (user != null) { _context.Users.Attach(user); // 把实体附加到上下文,让EF Core跟踪它 _context.Users.Remove(user); _context.SaveChanges(); } }
进阶建议:改用异步方法更适合API场景
API接口推荐用异步方法,这样能提升并发性能,你可以把控制器和仓储都改成异步版本:
控制器异步示例
[HttpDelete("{id}")] public async Task<ActionResult<User>> Delete(int id) { var user = await _userRepo.GetAsync(id); if(user != null) { await _userRepo.DeleteAsync(id); Console.WriteLine("is deleted."); } else { return NotFound(); } return NoContent(); } [HttpPost()] public async Task<IActionResult> Add([FromBody] UserCreateViewModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var newUser = new User { FirstName = model.FirstName, LastName = model.LastName, Email = model.Email, Platform = model.Platform, Is_enabled = model.Is_enabled, }; Console.WriteLine(newUser); await _userRepo.AddAsync(newUser); return CreatedAtAction(nameof(Get), new { newUser.Id }, newUser); }
仓储异步示例
public async Task<User> GetAsync(int id) { return await _context.Users.FindAsync(id); } public async Task DeleteAsync(int id) { var user = await _context.Users.FindAsync(id); if (user != null) { _context.Users.Remove(user); await _context.SaveChangesAsync(); } } public async Task AddAsync(User user) { _context.Users.Add(user); await _context.SaveChangesAsync(); }
你先检查下仓储层的实现,大概率就是没加SaveChanges的问题,改完应该就能正常同步到数据库了!
备注:内容来源于stack exchange,提问作者PyroDaan
相关产品推荐
相关产品推荐

