public async Task ExecuteAsync(DeleteImageAssetCommand command, IExecutionContext executionContext)
        {
            var imageAsset = await _dbContext
                             .ImageAssets
                             .FilterById(command.ImageAssetId)
                             .SingleOrDefaultAsync();

            if (imageAsset != null)
            {
                _dbContext.ImageAssets.Remove(imageAsset);

                var fileName = Path.ChangeExtension(imageAsset.FileNameOnDisk, imageAsset.FileExtension);
                var deleteUnstructuredDataComand = new DeleteUnstructuredDataDependenciesCommand(ImageAssetEntityDefinition.DefinitionCode, imageAsset.ImageAssetId);
                var deleteFileCommand            = new QueueAssetFileDeletionCommand()
                {
                    EntityDefinitionCode = ImageAssetEntityDefinition.DefinitionCode,
                    FileNameOnDisk       = imageAsset.FileNameOnDisk,
                    FileExtension        = imageAsset.FileExtension
                };

                using (var scope = _transactionScopeFactory.Create(_dbContext))
                {
                    await _dbContext.SaveChangesAsync();

                    await _commandExecutor.ExecuteAsync(deleteFileCommand, executionContext);

                    await _commandExecutor.ExecuteAsync(deleteUnstructuredDataComand, executionContext);

                    scope.QueueCompletionTask(() => OnTransactionComplete(command));

                    await scope.CompleteAsync();
                }
            }
        }
        public async Task ExecuteAsync(UpdateImageAssetCommand command, IExecutionContext executionContext)
        {
            bool hasNewFile = command.File != null;

            if (hasNewFile)
            {
                _assetFileTypeValidator.ValidateAndThrow(command.File.FileName, command.File.MimeType, nameof(command.File));
            }

            var imageAsset = await _dbContext
                             .ImageAssets
                             .Include(a => a.ImageAssetTags)
                             .ThenInclude(a => a.Tag)
                             .FilterById(command.ImageAssetId)
                             .SingleOrDefaultAsync();

            imageAsset.Title    = command.Title;
            imageAsset.FileName = SlugFormatter.ToSlug(command.Title);
            imageAsset.DefaultAnchorLocation = command.DefaultAnchorLocation;

            _entityTagHelper.UpdateTags(imageAsset.ImageAssetTags, command.Tags, executionContext);
            _entityAuditHelper.SetUpdated(imageAsset, executionContext);

            using (var scope = _transactionScopeFactory.Create(_dbContext))
            {
                if (hasNewFile)
                {
                    var deleteOldFileCommand = new QueueAssetFileDeletionCommand()
                    {
                        EntityDefinitionCode = ImageAssetEntityDefinition.DefinitionCode,
                        FileNameOnDisk       = imageAsset.FileNameOnDisk,
                        FileExtension        = imageAsset.FileExtension
                    };

                    imageAsset.FileUpdateDate = executionContext.ExecutionDate;
                    var fileStamp = AssetFileStampHelper.ToFileStamp(imageAsset.FileUpdateDate);
                    imageAsset.FileNameOnDisk = $"{imageAsset.ImageAssetId}-{fileStamp}";

                    await _commandExecutor.ExecuteAsync(deleteOldFileCommand);

                    await _imageAssetFileService.SaveAsync(command.File, imageAsset, nameof(command.File));
                }

                await _dbContext.SaveChangesAsync();

                scope.QueueCompletionTask(() => OnTransactionComplete(hasNewFile, imageAsset));

                await scope.CompleteAsync();
            }
        }
        public async Task ExecuteAsync(UpdateDocumentAssetCommand command, IExecutionContext executionContext)
        {
            bool hasNewFile = command.File != null;

            var documentAsset = await _dbContext
                                .DocumentAssets
                                .Include(a => a.DocumentAssetTags)
                                .ThenInclude(a => a.Tag)
                                .FilterById(command.DocumentAssetId)
                                .SingleOrDefaultAsync();

            documentAsset.Title       = command.Title;
            documentAsset.Description = command.Description ?? string.Empty;
            documentAsset.FileName    = FilePathHelper.CleanFileName(command.Title);

            if (string.IsNullOrWhiteSpace(documentAsset.FileName))
            {
                throw new PropertyValidationException("Document title is empty or does not contain any safe file path characters.", nameof(command.Title));
            }

            _entityTagHelper.UpdateTags(documentAsset.DocumentAssetTags, command.Tags, executionContext);
            _entityAuditHelper.SetUpdated(documentAsset, executionContext);

            using (var scope = _transactionScopeFactory.Create(_dbContext))
            {
                if (hasNewFile)
                {
                    var deleteOldFileCommand = new QueueAssetFileDeletionCommand()
                    {
                        EntityDefinitionCode = DocumentAssetEntityDefinition.DefinitionCode,
                        FileNameOnDisk       = documentAsset.FileNameOnDisk,
                        FileExtension        = documentAsset.FileExtension
                    };

                    await _commandExecutor.ExecuteAsync(deleteOldFileCommand);

                    await _documentAssetCommandHelper.SaveFile(command.File, documentAsset);

                    documentAsset.FileUpdateDate = executionContext.ExecutionDate;
                }

                await _dbContext.SaveChangesAsync();

                scope.QueueCompletionTask(() => OnTransactionComplete(documentAsset, hasNewFile));

                await scope.CompleteAsync();
            }
        }