C# API中HTTP DELETE返回200却未删除数据库数据的问题求助
C# API DELETE返回200但未删除数据库数据问题排查
问题描述
开发C# API应用时,GET方法正常工作,但DELETE方法返回200成功状态码,却没有删除数据库中的对应数据。采用了工作单元(Unit of Work)和仓储(Repository)模式。
排查与解决方案
1. 确认工作单元CommitAsync()的实现
工作单元的CommitAsync()是提交数据库修改的核心,必须确保它正确调用了EF Core的SaveChangesAsync()。当前提供的UnitOfWork类未包含该方法的实现,正确实现如下:
public async Task CommitAsync() { await _db.SaveChangesAsync(); }
如果CommitAsync()未实现或未正确调用SaveChangesAsync(),即使调用了该方法,修改也不会同步到数据库。
2. 检查是否获取到待删除的实体
如果OrderRepository.Get(id)返回null,EF Core的Remove(null)不会执行任何删除操作,且不会抛出异常,导致接口返回200但无实际修改。需在Delete方法中增加空值判断:
public async Task Delete(int id) { try { var order = await _unitOfWork.OrderRepository.Get(id); if (order == null) { throw new KeyNotFoundException($"ID为{id}的订单不存在"); } _unitOfWork.OrderRepository.Delete(order); await _unitOfWork.CommitAsync(); } catch (Exception e) { await _unitOfWork.RollbackAsync(); throw; } }
同时控制器可根据异常类型返回404状态码,更准确反馈结果:
[HttpDelete("{id}")] public async Task<ActionResult> RemoveOrder(int id) { try { await _orderService.Delete(id); return Ok(); } catch (KeyNotFoundException ex) { return NotFound(ex.Message); } catch (Exception ex) { return StatusCode(500); } }
3. 验证仓储Get(id)方法的正确性
通用仓储的Get(id)需正确从数据库查询实体,比如使用EF Core的FindAsync方法:
public async Task<T> Get(int id) { return await _db.Set<T>().FindAsync(id); }
如果Get方法的查询逻辑错误(如使用同步方法未等待、查询条件错误),会导致无法获取实体,进而无法执行删除。
4. 检查DbContext的依赖注入生命周期
确保NorthwindContext被注册为Scoped生命周期,避免单例上下文导致的状态不一致:
services.AddDbContext<NorthwindContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Northwind")), ServiceLifetime.Scoped);
若上下文为单例,多个请求共用同一实例可能导致修改未及时提交。
5. 排查事务或拦截器影响
如果存在全局事务拦截器、自定义SaveChanges拦截器,需确认它们未阻止删除操作的提交。
提供的相关代码
控制器代码
private readonly IOrderService _orderService; public OrdersController(IOrderService orderService) { _orderService = orderService; } [HttpDelete("{id}")] public async Task<ActionResult> RemoveOrder(int id) { try { await _orderService.Delete(id); return StatusCode(200); } catch (Exception ex) { return StatusCode(500); } }
服务接口
public interface IOrderService { Task<Order> Get(int id); Task Add(Order order); Task Delete(int id); Task Update(int id, Order order); Task<IEnumerable<Order>> GetAllOrdersAsync(); Task<IEnumerable<OrderDTO>> GetOrdersToCityAsync(string cityName); Task<OrderDTO> GetEmployeeOrdersToCountryAsync ( string countryName, string employeeLastName ); }
服务实现类
public class OrderService : IOrderService { private readonly IUnitOfWork _unitOfWork; public OrderService(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public async Task Delete(int id) { try { var order = await _unitOfWork.OrderRepository.Get(id); _unitOfWork.OrderRepository.Delete(order); await _unitOfWork.CommitAsync(); } catch (Exception e) { await _unitOfWork.RollbackAsync(); throw; } } }
工作单元类
public class UnitOfWork : IUnitOfWork { private readonly NorthwindContext _db; private List<object> _customRepositories = new List<object>(); private IProductRepository _productRepository; private IOrderRepository _orderRepository; public UnitOfWork( NorthwindContext db, IProductRepository ProductRepository, IOrderRepository orderRepository ) { _db = db; _productRepository = ProductRepository; _orderRepository = orderRepository; } }
工作单元接口
public interface IUnitOfWork { IProductRepository ProductRepository { get; } IOrderRepository OrderRepository { get; } Task CommitAsync(); Task RollbackAsync(); }
订单仓储接口
public interface IOrderRepository : IGenericRepository<Order> { Task<IEnumerable<OrderDTO>> GetOrdersToCityAsync(string cityName); Task<OrderDTO> GetEmployeeOrdersToCountryAsync ( string countryName, string employeeLastName ); }
订单仓储实现类
public class OrderRepository : GenericRepository<Order>, IOrderRepository { private readonly NorthwindContext _northwindContext; public OrderRepository(NorthwindContext db) : base(db) { _northwindContext = db; } }
通用仓储类
public class GenericRepository<T> : IGenericRepository<T> where T : class { protected readonly NorthwindContext _db; public GenericRepository(NorthwindContext db) { _db = db; } public void Delete(T entity) { _db.Set<T>().Remove(entity); } }
内容的提问来源于stack exchange,提问作者DS Assignment
相关产品推荐
相关产品推荐

