public async Task ExecuteAsync(QueryContext context) { var softDelete = _repo.SoftDelete; _repo.SoftDelete = context.Descriptor.SoftDelete; if (!string.IsNullOrEmpty(context.Params.Id)) { object[] id; try { id = _repo.ParseId(context.Params.Id); } catch (Exception ex) { throw new QueryException("id format incorrect", QueryErrorCode.BadRequest, ex); } if (context.Descriptor.OnlyOwnerCanDelete) { var authContext = new AuthorizationContext <T>(context); await _repo.RemoveAsync(id, async (newDto, oldDto, cancellationToken) => { var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.DeletePolicy); if (authorized) { return(true); } context.Fail(oldDto, QueryErrorCode.Unauthorized, "unauthorized"); return(false); }, (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"), context.CancellationToken); } else { await _repo.RemoveAsync(id, (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"), context.CancellationToken); } return; } if (context.IsArrayModel()) { var models = context.ToModels <T>() ?? throw new QueryException("models is required", QueryErrorCode.BadRequest); var errors = new List <RecordError>(models.Length); if (context.Descriptor.OnlyOwnerCanDelete) { var authContext = new AuthorizationContext <T>(context); await _repo.RemoveRangeAsync(models, async (newDto, oldDto, index, continuation, cancellationToken) => { var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.DeletePolicy); if (authorized) { return(true); } errors.Add(new RecordError { ErrorCode = QueryErrorCode.Unauthorized, ErrorDescription = QueryErrorCode.Unauthorized.ToString(), At = index }); continuation.Yes = true; return(false); }, (dto, index, continuation) => { errors.Add(new RecordError { ErrorCode = QueryErrorCode.NotFound, ErrorDescription = QueryErrorCode.NotFound.ToString(), At = index }); continuation.Yes = true; }, context.CancellationToken); } else { await _repo.RemoveRangeAsync(models, (dto, index, continuation) => { errors.Add(new RecordError { ErrorCode = QueryErrorCode.NotFound, ErrorDescription = QueryErrorCode.NotFound.ToString(), At = index }); continuation.Yes = true; }, context.CancellationToken); } if (errors.Count > 0) { context.Fail(errors, QueryErrorCode.ValidationError, QueryErrorCode.ValidationError.ToString()); } else { context.Succeed(models); } } else { var model = context.ToModel <T>() ?? throw new QueryException("model is required", QueryErrorCode.BadRequest); if (context.Descriptor.OnlyOwnerCanDelete) { var authContext = new AuthorizationContext <T>(context); await _repo.RemoveAsync(model, async (newDto, oldDto, cancellationToken) => { var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.DeletePolicy); if (authorized) { return(true); } context.Fail(newDto, QueryErrorCode.Unauthorized, "unauthorized"); return(false); }, (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"), context.CancellationToken); } else { await _repo.RemoveAsync(model, (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"), context.CancellationToken); } } _repo.SoftDelete = softDelete; }