异步方法上的 C# 实体框架错误
本文关键字:框架 错误 实体 异步方法 | 更新日期: 2023-09-27 18:35:21
我已经看到了这个,但我遇到了另一个问题。
我有这个服务类来管理 ASP.NET 身份角色:
public class RoleService : IRoleService
{
private readonly RoleManager<ApplicationRole> _roleManager;
public RoleService(RoleManager<ApplicationRole> roleManager)
{
this._roleManager = roleManager;
}
public async Task<IdentityResult> CreateAsync(ApplicationRole role)
{
return await this._roleManager.CreateAsync(role);
}
}
正如这个问题所建议的,我使用这样的CreateAsync
方法来避免使用 LINQ foreach
:
private async Task PopulateRoles()
{
var roles = new[] { "A", "B", "C", "D" };
// Used LINQ foreach previously but I coded this way instead to follow the related questions's answer
var tasks = roles.Select(role =>
this._roleService.CreateAsync(new ApplicationRole(role)))
.ToList();
await Task.WhenAll(tasks);
}
但是,这会导致在执行await this.PopulateRoles()
时出错。
实体框架:已有一个与此命令关联的打开的 DataReader,必须先关闭该读取器。
搜索此错误只会使我建议在选择 LINQ 中添加ToList()
。我该如何解决它?
问题在于内部被赋予单一DbContext
的RoleManager<T>
,我们在这里看到:
public class RoleStore<TRole, TContext, TKey> :
IQueryableRoleStore<TRole>,
IRoleClaimStore<TRole>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TContext : DbContext
{
public RoleStore(TContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
Context = context;
}
}
DbContext
本身无法处理并发呼叫。另一种方法是在foreach
内执行每个调用并await
每个调用:
private async Task PopulateRoles()
{
var roles = new[] { "A", "B", "C", "D" };
foreach (var role in roles)
{
await _roleService.CreateAsync(new ApplicationRole(role));
}
}
这样,尽管您没有同时应用所有角色的好处,但您仍然可以利用 IO 调用的异步特性,而不是阻止同步调用。