.NET 8 Web应用获取指定公司用户及角色时遇MySQL连接占用错误
解决"MySqlConnection is already in use"错误
错误原因
_userManager.Users.Where(...)返回的是延迟执行的IQueryable对象,在foreach循环遍历它的过程中,循环内部又调用了_userManager.FindByIdAsync、GetRolesAsync这类会发起数据库请求的异步方法,导致同一个MySQL连接被多个操作同时占用,触发连接冲突异常。
修复步骤
把查询到的公司用户列表先立即执行,转换成内存中的集合,再进行后续的循环处理,避免遍历未执行的查询时同时发起新的数据库请求。另外,循环里的FindByIdAsync属于多余操作,直接使用已查询到的companyUser对象即可,能减少不必要的数据库请求。
修改后的代码
public IndexModel(UserManager<ApplicationUser> userManager) { _userManager = userManager; } public async Task<IActionResult> OnGet() { ApplicationUser user = await _userManager.GetUserAsync(User); ValidatePermission Validate = new ValidatePermission(_context, _userManager); if (!await Validate.validateAdmin(user)) { return RedirectToPage("/InvalidPermissions"); } // 调用ToListAsync()立即执行查询,将结果加载到内存中 var users = await _userManager.Users .Where(u => u.Company_ID == user.Company_ID && u.Id != user.Id) .ToListAsync(); Users = new List<CompanyUserViewModel>(); foreach (var companyUser in users) { var userRoles = await _userManager.GetRolesAsync(companyUser); CompanyUserViewModel userView = new CompanyUserViewModel(); userView.ID = companyUser.Id; userView.Name = companyUser.FirstName + " " + companyUser.LastName; userView.Role = userRoles.Contains("Admin") ? "Admin" : userRoles.Contains("Manager") ? "Manager" : "User"; userView.JobTitle = companyUser.JobTitle; userView.Email = companyUser.Email; Users.Add(userView); } return Page(); }
内容的提问来源于stack exchange,提问作者Ben Dove
相关产品推荐
相关产品推荐

