Невозможно получить доступ к удаленному объекту в asp core 3, когда необходимо обновить буксируемый объект - PullRequest
0 голосов
/ 30 апреля 2020

сначала объясните мой 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

в чем проблема? как я могу решить эту проблему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...