ASP.Net - Ошибка контекста данных пользователя в сервисе
Добавил в ASP.Net (.Net 6) проекте scoped-сервис, куда вынес usermanager и rolemanager (у меня на сайте есть нюанс работы с ними). Первая загрузка информации о пользователке проходит идеально, а вот вторая и далее выдаёт ошибку:
InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
Я так понимаю из этого вопроса, что копать надо здесь:
#region 7. Роли пользователя
#region 7.1. Операции с группами
/// <summary>
/// Проверка существования роли
/// </summary>
/// <param name="roleid">Идентификатор роли</param>
/// <returns>Существует ли роль</returns>
public async Task<bool> IsRoleExistsAsync ([NotNull] string roleid)
{
logger.LogInformation($"Checking role with ID {roleid} is exists.");
return await data.RolesRecords.AnyAsync(role => role.RoleId == roleid);
}
/// <summary>
/// Добавляет роль
/// </summary>
/// <param name="roleid">Идентификатор роли</param>
/// <param name="rolename">Имя роли</param>
/// <returns>Нет возвращаемого значения</returns>
public async Task AddRoleAsync ([NotNull] string roleid, [NotNull] string rolename)
{
if (await IsRoleExistsAsync(roleid))
return;
logger.LogInformation($"Add role \"{roleid} = {rolename}\".");
RoleRecord record = new()
{
RoleId = roleid,
RoleName = rolename
};
await data.RolesRecords.AddAsync(record);
await data.SaveChangesAsync();
await rolemanager.CreateAsync(new IdentityRole<Guid>(roleid));
}
/// <summary>
/// Получение записи о роли
/// </summary>
/// <param name="roleid">Идентификатор роли</param>
/// <returns>Запись о роли или null (если не найдено)</returns>
[ItemCanBeNull]
public async Task<RoleRecord> GetRoleAsync ([NotNull] string roleid)
{
logger.LogInformation($"Get role with id {roleid} from database.");
return await data.RolesRecords.FirstAsync(role => role.RoleId == roleid);
}
/// <summary>
/// Получение имени роли по ID.
/// </summary>
/// <param name="roleid">Название роли</param>
/// <returns>Название группы</returns>
[ItemNotNull]
public async Task<string> GetRoleName ([NotNull] string roleid) => (await IsRoleExistsAsync(roleid)) ? (await GetRoleAsync(roleid)).RoleName : "Не определена";
/// <summary>
/// Получение всех ролей
/// </summary>
/// <returns>Запись о роли или null (если не найдено)</returns>
[CanBeNull]
public IQueryable<RoleRecord> GetAllRoles ()
{
logger.LogInformation($"Get all roles.");
return data.RolesRecords.ToList().AsQueryable();
}
/// <summary>
/// Получение всех идентификаторов ролей
/// </summary>
/// <returns>Список идентификаторов ролей</returns>
[CanBeNull]
public IEnumerable<string> GetAllRolesIds ()
{
logger.LogInformation($"Get all roles id.");
IQueryable<RoleRecord> roles = GetAllRoles();
List<string> allrolesids = new();
foreach (RoleRecord role in roles)
allrolesids.Add(role.RoleId);
return allrolesids.AsEnumerable();
}
/// <summary>
/// Обновляет имя роли
/// </summary>
/// <param name="roleid">Идентификатор роли</param>
/// <param name="newrolename">Новое имя роли</param>
/// <returns>Нет возвращаемого значения</returns>
public async Task UpdateRoleNameAsync ([NotNull] string roleid, [NotNull] string newrolename)
{
//Проверка существования роли
if (!await IsRoleExistsAsync(roleid))
return;
logger.LogInformation($"Update role's name with id {roleid} to {newrolename}.");
RoleRecord record = await GetRoleAsync(roleid);
record.RoleName = newrolename;
data.RolesRecords.Update(record);
await data.SaveChangesAsync();
}
public async Task DeleteRoleAsync ([NotNull] string roleid)
{
if (!await IsRoleExistsAsync(roleid))
return;
RoleRecord record = await GetRoleAsync(roleid);
if (record == null)
return;
IdentityRole<Guid> role = rolemanager.Roles.FirstOrDefault(rl => rl.Name == roleid);
if (role == null)
return;
data.RolesRecords.Remove(record);
await data.SaveChangesAsync();
await rolemanager.DeleteAsync(role);
logger.LogInformation($"Role with ID {roleid} was removed.");
}
#endregion
#region 7.2 Операции с пользователями
/// <summary>
/// Проверяет, принадлежит ли пользователь роли
/// </summary>
/// <param name="user">Пользователь</param>
/// <param name="roleid">Идентификатор группы</param>
/// <returns>true - принадлежит, false - не принадлежит</returns>
public async Task<bool> IsUserInRoleAsync ([NotNull] RnrmmUser user, string roleid)
{
logger.LogInformation($"Checking, is user with ID {roleid} in group with ID {roleid}.");
return await usermanager.IsInRoleAsync(user, roleid);
}
/// <summary>
/// Получает идентификатор роли пользователя
/// </summary>
/// <param name="user">Пользователь</param>
/// <returns>Идентификатор роли пользователя</returns>
[ItemNotNull]
public async Task<string> GetUserGroupAsync ([NotNull] RnrmmUser user)
{
logger.LogInformation($"Getting user group for user with ID {user.Id}.");
IList<string> roles = await usermanager.GetRolesAsync(user);
return roles.FirstOrDefault() ?? string.Empty;
}
/// <summary>
/// Добавляет нового пользователя к роли / перемещает пользователя в роль
/// </summary>
/// <param name="user">Пользователь</param>
/// <param name="roleid">Идентификатор роли</param>
/// <returns>Статус операции</returns>
public async Task<IdentityResult> AddUserToRole (RnrmmUser user, [NotNull] string roleid)
{
if (!await IsRoleExistsAsync(roleid))
{
logger.LogError($"Role with id {roleid} is not found!");
return IdentityResult.Failed(new IdentityError() { Code = "1", Description = $"Role with id {roleid} is not found!" });
}
if (user == null)
{
logger.LogError($"User is not found!");
return IdentityResult.Failed(new IdentityError() { Code = "1", Description = $"User is not found!" });
}
//Удаляем все роли, записанные на пользователя
await usermanager.RemoveFromRolesAsync(user, GetAllRolesIds());
//Устанавливаем роль roleid
IdentityResult result = await usermanager.AddToRoleAsync(user, roleid);
RoleRecord record = await GetRoleAsync(roleid);
logger.LogInformation($"Adding user to group {record.RoleName} with result {result}.");
return result;
}
#endregion
#endregion
Но где именно, ума не приложу. Заранее спасибо за советы!