public ActionResult PartiallyUpdateMaterialForPerson(Guid personId,
                                                             Guid materialId,
                                                             JsonPatchDocument <MaterialForUpdateDto> patchDocument)
        {
            if (!_materialRepository.PersonExists(personId))
            {
                return(NotFound());
            }

            var materialFromRepo = _materialRepository.GetMaterial(personId, materialId);

            if (materialFromRepo == null)
            {
                var materialDto = new MaterialForUpdateDto();

                patchDocument.ApplyTo(materialDto, ModelState);

                if (!TryValidateModel(materialDto))
                {
                    return(ValidationProblem(ModelState));
                }

                var materialToAdd = _mapper.Map <Material>(materialDto);
                materialToAdd.Id = materialId;

                _materialRepository.AddMaterial(personId, materialToAdd);
                _materialRepository.Save();

                var materialToReturn = _mapper.Map <MaterialDto>(materialToAdd);

                return(CreatedAtRoute("GetMaterialForPerson",
                                      new { personId, materialId = materialToReturn.Id },
                                      materialToReturn));
            }

            var materialToPatch = _mapper.Map <MaterialForUpdateDto>(materialFromRepo);

            patchDocument.ApplyTo(materialToPatch, ModelState);

            if (!TryValidateModel(materialToPatch))
            {
                return(ValidationProblem(ModelState));
            }

            _mapper.Map(materialToPatch, materialFromRepo);

            _materialRepository.UpdateMaterial(materialFromRepo);

            _materialRepository.Save();

            return(NoContent());
        }
        public IActionResult UpdateMaterialForPerson(Guid personId, Guid materialId, MaterialForUpdateDto material)
        {
            if (!_materialRepository.PersonExists(personId))
            {
                return(NotFound());
            }

            var materialFromRepo = _materialRepository.GetMaterial(personId, materialId);

            if (materialFromRepo == null)
            {
                var materialToAdd = _mapper.Map <Material>(material);
                materialToAdd.Id = materialId;

                _materialRepository.AddMaterial(personId, materialToAdd);

                _materialRepository.Save();

                var materialToReturn = _mapper.Map <MaterialDto>(materialToAdd);

                return(CreatedAtRoute("GetMaterialForPerson",
                                      new { personId, materialId = materialToReturn.Id },
                                      materialToReturn));
            }

            // Map the entity to a MaterialForUpdateDto
            _mapper.Map(material, materialFromRepo);

            // Apply the updated field values to that entity
            _materialRepository.UpdateMaterial(materialFromRepo);

            // By executing the mapper the entity has changed to a modified
            // state and executing the save will write the changes to our database
            _materialRepository.Save();

            // Map the MaterialForUpdateDto back to an entity

            // We can return an OK or NoContent. The best one depends on the use case
            return(NoContent());
        }