【发布时间】:2022-03-24 16:39:53
【问题描述】:
我在调用下面的以下代码块时收到此错误。我在 SO 上看到的与此错误相关的所有内容都是由于人们调用了 using 块,我不是,但在幕后可能有一些我不知道被重复的代码?我也不确定如何找到这里复制的连接。有一些专业知识的人可以在这个问题上提供帮助吗?我的堆栈跟踪也在下面。
if (await _userManager.IsInRoleAsync(user, role.Name))
public class UserRolesModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly IAdminView _adminView;
public UserRolesModel(UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
RoleManager<IdentityRole> roleManager,
IAdminView adminView)
{
_userManager = userManager;
_signInManager = signInManager;
_roleManager = roleManager;
_adminView = adminView;
}
public EmployeeDto Employee { get; set; }
public ManageUserRolesDto UserRoles { get; set; }
public async Task OnGetAsync(string userId)
{
var userRoleList = new List<UserRolesDto>();
var user = await _userManager.FindByIdAsync(userId);
foreach (var role in _roleManager.Roles)
{
var userRolesDto = new UserRolesDto()
{
RoleName = role.Name
};
if (await _userManager.IsInRoleAsync(user, role.Name))
{
userRolesDto.Selected = true;
}
else
{
userRolesDto.Selected = false;
}
userRoleList.Add(userRolesDto);
}
UserRoles = new ManageUserRolesDto()
{
UserId = userId,
UserRoles = userRoleList
};
var employeeData = await _adminView.GetEmployeeDataByAspId(userId);
var viewModel = new EmployeeViewDto
{
Employee = employeeData
};
Employee = new EmployeeDto
{
EmployeeAspId = employeeData.AspUserId,
EmployeeViewDto = viewModel
};
}
public async Task<IActionResult> OnPostAsync(string id, ManageUserRolesDto userRoles)
{
var user = await _userManager.FindByIdAsync(id);
var roles = await _userManager.GetRolesAsync(user);
var result = await _userManager.RemoveFromRolesAsync(user, roles);
result = await _userManager.AddToRolesAsync(user, userRoles.UserRoles.Where(x => x.Selected).Select(y => y.RoleName));
var currentUser = await _userManager.GetUserAsync(User);
await _signInManager.RefreshSignInAsync(currentUser);
await Data.Seeds.DefaultUsers.SeedSuperAdminAsync(_userManager, _roleManager);
return RedirectToPage("/Admin/Index");
}
}
堆栈跟踪
System.InvalidOperationException: There is already an open DataReader associated with this Connection which must be closed first.
at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__169_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9.IsInRoleAsync(TUser user, String normalizedRoleName, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Identity.UserManager`1.IsInRoleAsync(TUser user, String role)
at Navrae.WebApp.Pages.RoleManager.UserRolesModel.OnGetAsync(String userId) in C:\Users\Work Laptop\source\repos\Navrae\Navrae.WebApp\Pages\RoleManager\UserRoles.cshtml.cs:line 45
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.NonGenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
【问题讨论】:
-
尝试将
foreach (var role in _roleManager.Roles)更改为foreach (var role in _roleManager.Roles.ToList()) -
我切换回本地数据库,它工作正常。不确定它是否是我在 SQL 服务器上的设置导致问题。
-
对于 SQL Server,你必须启用 MARS -“多个活动结果集”,谷歌它,你应该找到如何配置你的连接字符串来启用它。
-
我根据您的建议对其进行了测试,并且成功了。我不知道为什么。也许 MARS 的研究会给出答案。谢谢@LasseV.Karlsen!
-
不同之处在于,使用
.ToList(),您在进入循环体之前消耗了Roles集合,这意味着就数据库连接而言,您已经完成了角色的迭代。没有它,当您还尝试执行IsInRoleAsync时,您将针对 Roles 集合的数据库打开结果集,然后还尝试获取结果集。
标签: sql asp.net-core entity-framework-core sqldatareader