异步方法上的 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()。我该如何解决它?

异步方法上的 C# 实体框架错误

问题在于内部被赋予单一DbContextRoleManager<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 调用的异步特性,而不是阻止同步调用。