private async Task BatchDeleteEntitiesAsync <TEntity>(Expression <Func <TEntity, bool> > predicate, CancellationToken cancellationToken) where TEntity : class, IIdentityPrimaryKey, new() { using (var dbContext = _dbContextFactory.Create()) { var entities = await dbContext .Query <TEntity>() .AsNoTracking() .Where(predicate) .Select(x => new TEntity { Id = x.Id }) .ToArrayAsync(cancellationToken).ConfigureAwait(false); _logger.LogDebug($"{entities.Length} {typeof(TEntity).Name}(s) are ready to purge."); var batchDeleteBlock = new BatchExecuteTargetBlock <TEntity>( elements => RemoveEntitiesInternalAsync(elements, cancellationToken), Options.Concurrency, cancellationToken); foreach (var entity in entities) { _ = await batchDeleteBlock.SendAsync(entity, cancellationToken).ConfigureAwait(false); } batchDeleteBlock.Complete(); await batchDeleteBlock.Completion.AggregateExceptions <DataPurgingException>( "Purging of PredictionSchedules data has been failed. See inner exception for more details."); _logger.LogDebug( $"Purging of {entities.Length} {typeof(TEntity).Name}(s) has been completed successfully according to the '{nameof(Options.DaysAfter)}' parameter."); } }
public override async Task ExecuteAsync(CancellationToken cancellationToken) { if (Options.DaysAfter == 0) { _logger.LogDebug( $"'{nameof(Options.DaysAfter)}' configuration parameters hasn't been specified, execution skipped."); return; } var thresholdDate = _clock.GetCurrentInstant().ToDateTimeUtc().AddDays(-Options.DaysAfter); var campaignIds = await _dbContext.Query <Campaign>().AsNoTracking() .Where(x => x.EndDateTime < thresholdDate) .Select(x => x.Id).ToArrayAsync(cancellationToken).ConfigureAwait(false); _logger.LogDebug( $"'{nameof(Options.DaysAfter)}' parameter is set to {Options.DaysAfter} days. {campaignIds.Length} campaign(s) returned which end date less than {thresholdDate}."); if (campaignIds.Length > 0) { var targetBlock = new BatchExecuteTargetBlock <Guid>( ids => _campaignCleaner.ExecuteAsync(ids, cancellationToken), Options.Concurrency, cancellationToken); foreach (var campaignId in campaignIds) { _ = await targetBlock.SendAsync(campaignId, cancellationToken).ConfigureAwait(false); } targetBlock.Complete(); await targetBlock.Completion.AggregateExceptions <DataPurgingException>( "Purging of Campaign data has been failed. See inner exception for more details."); _logger.LogDebug( $"Purging of {campaignIds.Length} campaign(s) has been completed successfully according to the '{nameof(Options.DaysAfter)}' parameter."); } }