简体   繁体   中英

EF Core async select InvalidOperationException

The following code

var merchant = await _dbContext.Merchants
   .Include(m => m.Users)
   .SingleAsync(m => m.MerchantId == id);
 
var userTasks = merchant.Users.Select(async u =>
{
   var roles = await _userManager.GetRolesAsync(u);

   return new MerchantUser
   {
      UserName = u.UserName,
      Role = string.Join(",", roles)
   };
}).ToList();

var users = await Task.WhenAll(userTasks);
            
return View(new MerchantViewModel
{
   MerchantId = merchant.MerchantId,
   MerchantName = merchant.Name,
   MerchantUsers = users.ToList()
});

sometimes returns this error:

System.InvalidOperationException: A second operation started on this context before a previous operation completed.

However, this code does not. To my understanding, it's doing the same thing so I don't understand why it's failing.

var merchant = await _dbContext.Merchants
    .Include(m => m.Users)
    .SingleAsync(m => m.MerchantId == id);

var users = new List<MerchantUser>();
            
foreach (var user in merchant.Users)
{
    var roles = await _userManager.GetRolesAsync(user);
                
    users.Add(new MerchantUser
    {
        UserName = user.UserName,
        Role = string.Join(",", roles)
    });
}
            
return View(new MerchantViewModel
{
    MerchantId = merchant.MerchantId,
    MerchantName = merchant.Name,
    MerchantUsers = users
});
var userTasks = merchant.Users.Select(async u => { … }).ToList();
var users = await Task.WhenAll(userTasks);

This will asynchronously start all those Select tasks at the same time and then wait for them to complete. So this will run multiple things in parallel. Since you are querying the user manager inside, this will not work since the underlying connection does not support parallel queries.

In contrast, your foreach loop will only run one query at a time, awaiting the GetRolesAsync before the next iteration begins. So instead of working in parallel, the roles will be read sequentially for all users.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM