获取当前用户专属SelectList时遭遇DbContext并发操作异常
解决DbContext并发异常与正确筛选当前用户关联数据的问题
问题背景
你想要在Create页面的下拉选择框(SelectList)中,仅展示当前登录用户对应的客户、产品和分类数据。最初的代码因为筛选条件错误(误用了实体ID和用户ID匹配)只能拿到第一条数据,修改筛选条件后又触发了InvalidOperationException,提示上下文存在未完成的并发操作。
错误原因分析
出现这个异常的核心问题有三个:
- 异步方法未等待:
_userManager.GetUserAsync(HttpContext.User)是异步方法,你直接访问currentUser.Id时,这个Task还没有执行完成,不仅拿不到正确的用户ID,还会导致后续对DbContext的查询操作同时启动。 - DbContext非线程安全:Entity Framework的DbContext实例不支持同时执行多个操作,当多个查询在同一个DbContext上并行执行时,就会抛出这个并发异常。
- 代码笔误:你更新后的代码里,把
ViewData["ProductId"]错误地先赋值为Categories的查询,后来又覆盖成Products的,导致分类的SelectList没有正确设置。
修复后的完整代码
public async Task<IActionResult> Create() { // 等待异步方法完成,获取当前登录用户的完整信息 var currentUser = await _userManager.GetUserAsync(HttpContext.User); string userId = currentUser.Id.ToString(); // 正确筛选当前用户关联的客户数据 ViewData["CustomerId"] = new SelectList( _context.Customers.Where(c => c.ApplicationUserId == userId), "ID", "Name"); // 正确筛选当前用户关联的分类数据 ViewData["CategoryId"] = new SelectList( _context.Categories.Where(c => c.ApplicationUserId == userId), "CategoryId", "CategoryName"); // 正确筛选当前用户关联的产品数据 ViewData["ProductId"] = new SelectList( _context.Products.Where(p => p.ApplicationUserId == userId), "ProductId", "ProductName"); return View(); }
关键修复点说明
- 异步方法必须await:把方法返回类型改为
Task<IActionResult>,并用await等待GetUserAsync完成,确保拿到的是真实的用户对象,而不是未完成的Task。 - 正确的关联筛选:使用
ApplicationUserId(数据库中关联用户的字段)和当前用户的Id进行匹配,这才是筛选当前用户所属数据的正确条件。 - 避免DbContext并发操作:
await不仅能拿到正确的用户ID,还能确保在执行后续DbContext查询时,前面的异步操作已经完成,不会出现多个操作同时访问DbContext的情况。 - 修正笔误:把原本错误赋值给
ProductId的分类查询,改为赋值给CategoryId,确保三个下拉框都能拿到对应的数据。
内容的提问来源于stack exchange,提问作者techstack
相关产品推荐
相关产品推荐

