сначала объясните мой senario:
я хочу изменить AccessLevel роли и, когда после этого изменить AccesLevel, измените securityStamp of Role.
сначала для этого я отправляю список предметы и проверить, существуют ли они в базе данных или нет. если существует, игнорируйте это, а если не существует Add
или не существует в списке от клиента, и exsist в базе данных должен удалить это:
public class AccessLevelsRpostiory : IAccessLevelRepository
{
private FilmstanContext context;
private DbSet<AccessLevel> AccessLevels { get; set; }
public AccessLevelsRpostiory(FilmstanContext context)
{
this.context = context;
AccessLevels = context.Set<AccessLevel>();
}
public async Task<OperationResult<string>> SetAccess(AccessLevelDto accessLevels)
{
try
{
var currentRoleAccessValue = GetAccessLevels(accessLevels.RoleId);
var currentAccess = currentRoleAccessValue.Select(x => x.Access).ToList();
var newAccess = accessLevels.Access.Except(currentAccess).ToList();
if (newAccess != null)
{
foreach (var item in newAccess)
{
AccessLevels.Add(new AccessLevel
{
Access = item,
RoleId = accessLevels.RoleId
});
}
}
var removeItems = currentAccess.Except(accessLevels.Access).ToList();
if (removeItems != null)
{
foreach (var item in removeItems)
{
var accClaim = currentRoleAccessValue.SingleOrDefault(x => x.Access == item);
if (accClaim != null)
{
AccessLevels.Remove(accClaim);
}
}
}
return OperationResult<string>.BuildSuccessResult("SuccessAdd");
}
catch (Exception ex)
{
return OperationResult<string>.BuildFailure(ex);
}
}
public IEnumerable<AccessLevel> GetAccessLevels(Guid roleId)
{
return AccessLevels.AsNoTracking().Where(x => x.RoleId == roleId).ToList();
}
}
в этой функции я получаюAllAccess Список для базы данных:
public IEnumerable<AccessLevel> GetAccessLevels(Guid roleId)
{
return AccessLevels.AsNoTracking().Where(x => x.RoleId == roleId).ToList();
}
на втором шаге, после проверки Add
и Remove
для уровня доступа я должен обновить Role SecurityStamp
.
var findRole = await unitOfWork.RoleRepository.GetRoleByIdAsync(request.RoleId, cancellationToken);
findRole.Result.UpdateSecurityStamp();
и после всего этого я вызываю await context.SaveChangesAsync();
:
public async Task CommitSaveChangeAsync()
{
try
{
await context.SaveChangesAsync();
}
catch (Exception ex)
{
throw ex;
}
}
, и это мой код для поиска Роли:
public class RolesRepository : IRoleRepository, IScoped
{
public IAccessLevelRepository AccessLevelRepository { get; set; }
private readonly FilmstanContext context;
private DbSet<Role> RoleEntite { get; set; }
public RolesRepository(FilmstanContext context)
{
this.context = context;
AccessLevelRepository = new AccessLevelsRpostiory(context);
RoleEntite = context.Set<Role>();
}
public async Task<OperationResult<Role>> GetRoleByIdAsync(Guid key, CancellationToken cancellation)
{
try
{
var role = await RoleEntite.AsNoTracking().FirstOrDefaultAsync(x => x.Id == key);
return OperationResult<Role>.BuildSuccessResult(role);
}
catch (Exception ex)
{
return OperationResult<Role>.BuildFailure(ex.Message);
}
}
}
}
это мой полный код:
public async Task<OperationResult<string>> Handle(SetAccessLevelCommand request, CancellationToken cancellationToken)
{
var result = await unitOfWork.RoleRepository.AccessLevelRepository.SetAccess(new AccessLevelDto { RoleId = request.RoleId, Access = request.AccessList });
if (result.Success)
{
try
{
var findRole = await unitOfWork.RoleRepository.GetRoleByIdAsync(request.RoleId, cancellationToken);
findRole.Result.UpdateSecurityStamp();
if (findRole.Result != null)
{
unitOfWork.RoleRepository.Update(findRole.Result, cancellationToken);
await unitOfWork.CommitSaveChangeAsync();
return OperationResult<string>.BuildSuccessResult("Add Success");
}
}
catch (Exception ex)
{
return OperationResult<string>.BuildFailure(ex.Message);
}
}
return OperationResult<string>.BuildFailure(result.ErrorMessage);
}
теперь он показывает эту ошибку, когда я звоню SaveChangeAsync()
Невозможно получить доступ к распоряжаться объектом. Распространенной причиной этой ошибки является удаление контекста, который был разрешен путем внедрения зависимости, а затем попытка использовать тот же экземпляр контекста в другом месте вашего приложения. Это может произойти, если вы вызываете Dispose () для контекста или переносите контекст i
в чем проблема? как я могу решить эту проблему?