/// <inheritdoc /> public virtual async Task <TResource> CreateAsync(TResource resource, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new { resource }); ArgumentGuard.NotNull(resource, nameof(resource)); TResource resourceFromRequest = resource; _resourceChangeTracker.SetRequestedAttributeValues(resourceFromRequest); _hookExecutor.BeforeCreate(resourceFromRequest); TResource resourceForDatabase = await _repositoryAccessor.GetForCreateAsync <TResource, TId>(resource.Id, cancellationToken); _resourceChangeTracker.SetInitiallyStoredAttributeValues(resourceForDatabase); try { await _repositoryAccessor.CreateAsync(resourceFromRequest, resourceForDatabase, cancellationToken); } catch (DataStoreUpdateException) { if (!Equals(resourceFromRequest.Id, default(TId))) { TResource existingResource = await TryGetPrimaryResourceByIdAsync(resourceFromRequest.Id, TopFieldSelection.OnlyIdAttribute, cancellationToken); if (existingResource != null) { throw new ResourceAlreadyExistsException(resourceFromRequest.StringId, _request.PrimaryResource.PublicName); } } await AssertResourcesToAssignInRelationshipsExistAsync(resourceFromRequest, cancellationToken); throw; } TResource resourceFromDatabase = await TryGetPrimaryResourceByIdAsync(resourceForDatabase.Id, TopFieldSelection.WithAllAttributes, cancellationToken); AssertPrimaryResourceExists(resourceFromDatabase); _hookExecutor.AfterCreate(resourceFromDatabase); _resourceChangeTracker.SetFinallyStoredAttributeValues(resourceFromDatabase); bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges(); if (!_options.AlwaysReturnResourceOnCreateUpdate && !hasImplicitChanges) { return(null); } _hookExecutor.OnReturnSingle(resourceFromDatabase, ResourcePipeline.Post); return(resourceFromDatabase); }
/// <inheritdoc /> public virtual async Task <TResource> CreateAsync(TResource resource, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new { resource }); if (resource == null) { throw new ArgumentNullException(nameof(resource)); } _resourceChangeTracker.SetRequestedAttributeValues(resource); var defaultResource = _resourceFactory.CreateInstance <TResource>(); defaultResource.Id = resource.Id; _resourceChangeTracker.SetInitiallyStoredAttributeValues(defaultResource); _hookExecutor.BeforeCreate(resource); try { await _repositoryAccessor.CreateAsync(resource, cancellationToken); } catch (DataStoreUpdateException) { var existingResource = await TryGetPrimaryResourceByIdAsync(resource.Id, TopFieldSelection.OnlyIdAttribute, cancellationToken); if (existingResource != null) { throw new ResourceAlreadyExistsException(resource.StringId, _request.PrimaryResource.PublicName); } await AssertResourcesToAssignInRelationshipsExistAsync(resource, cancellationToken); throw; } var resourceFromDatabase = await TryGetPrimaryResourceByIdAsync(resource.Id, TopFieldSelection.WithAllAttributes, cancellationToken); AssertPrimaryResourceExists(resourceFromDatabase); _hookExecutor.AfterCreate(resourceFromDatabase); _resourceChangeTracker.SetFinallyStoredAttributeValues(resourceFromDatabase); bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges(); if (!hasImplicitChanges) { return(null); } _hookExecutor.OnReturnSingle(resourceFromDatabase, ResourcePipeline.Post); return(resourceFromDatabase); }
/// <inheritdoc /> public virtual async Task <TResource> UpdateAsync(TId id, TResource requestResource) { _traceWriter.LogMethodStart(new { id, requestResource }); if (requestResource == null) { throw new ArgumentNullException(nameof(requestResource)); } TResource databaseResource = await GetPrimaryResourceById(id, false); _resourceChangeTracker.SetInitiallyStoredAttributeValues(databaseResource); _resourceChangeTracker.SetRequestedAttributeValues(requestResource); if (_hookExecutor != null) { requestResource = _hookExecutor.BeforeUpdate(AsList(requestResource), ResourcePipeline.Patch).Single(); } await _repository.UpdateAsync(requestResource, databaseResource); if (_hookExecutor != null) { _hookExecutor.AfterUpdate(AsList(databaseResource), ResourcePipeline.Patch); _hookExecutor.OnReturn(AsList(databaseResource), ResourcePipeline.Patch); } _repository.FlushFromCache(databaseResource); TResource afterResource = await GetPrimaryResourceById(id, false); _resourceChangeTracker.SetFinallyStoredAttributeValues(afterResource); bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges(); return(hasImplicitChanges ? afterResource : null); }
public virtual async Task <TResource> UpdateAsync(TId id, TResource requestEntity) { _logger.LogTrace($"Entering {nameof(UpdateAsync)}('{id}', {(requestEntity == null ? "null" : "object")})."); TResource databaseEntity = await _repository.Get(id).FirstOrDefaultAsync(); if (databaseEntity == null) { string resourceId = TypeHelper.GetResourceStringId <TResource, TId>(id, _resourceFactory); throw new ResourceNotFoundException(resourceId, _currentRequestResource.ResourceName); } _resourceChangeTracker.SetInitiallyStoredAttributeValues(databaseEntity); _resourceChangeTracker.SetRequestedAttributeValues(requestEntity); requestEntity = IsNull(_hookExecutor) ? requestEntity : _hookExecutor.BeforeUpdate(AsList(requestEntity), ResourcePipeline.Patch).Single(); await _repository.UpdateAsync(requestEntity, databaseEntity); if (!IsNull(_hookExecutor, databaseEntity)) { _hookExecutor.AfterUpdate(AsList(databaseEntity), ResourcePipeline.Patch); _hookExecutor.OnReturn(AsList(databaseEntity), ResourcePipeline.Patch); } _repository.FlushFromCache(databaseEntity); TResource afterEntity = await _repository.Get(id).FirstOrDefaultAsync(); _resourceChangeTracker.SetFinallyStoredAttributeValues(afterEntity); bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges(); return(hasImplicitChanges ? afterEntity : null); }
public virtual async Task <TResource> UpdateAsync(TId id, TResource requestResource) { _logger.LogTrace($"Entering {nameof(UpdateAsync)}('{id}', {(requestResource == null ? "null" : "object")})."); TResource databaseResource = await GetPrimaryResourceById(id, false); _resourceChangeTracker.SetInitiallyStoredAttributeValues(databaseResource); _resourceChangeTracker.SetRequestedAttributeValues(requestResource); if (_hookExecutor != null) { requestResource = _hookExecutor.BeforeUpdate(AsList(requestResource), ResourcePipeline.Patch).Single(); } await _repository.UpdateAsync(requestResource, databaseResource); if (_hookExecutor != null) { _hookExecutor.AfterUpdate(AsList(databaseResource), ResourcePipeline.Patch); _hookExecutor.OnReturn(AsList(databaseResource), ResourcePipeline.Patch); } _repository.FlushFromCache(databaseResource); TResource afterResource = await GetPrimaryResourceById(id, false); _resourceChangeTracker.SetFinallyStoredAttributeValues(afterResource); bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges(); return(hasImplicitChanges ? afterResource : null); }