public void CreateTestData(TestData data)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            foreach (var member in data.Members)
            {
                CreateMember(member);
            }

            foreach (var player in data.Players)
            {
                CreatePlayer(player);
            }

            foreach (var school in data.Schools)
            {
                CreateSchool(school);
            }

            foreach (var team in data.Teams)
            {
                if (team.Club != null)
                {
                    CreateClub(team.Club);
                }
                CreateTeam(team);
            }
            foreach (var playerIdentity in data.PlayerIdentities)
            {
                CreatePlayerIdentity(playerIdentity);
            }
            foreach (var location in data.MatchLocations)
            {
                CreateMatchLocation(location);
            }

            foreach (var team in data.Teams)
            {
                foreach (var location in team.MatchLocations)
                {
                    AddTeamToMatchLocation(team, location);
                }
            }

            foreach (var competition in data.Competitions)
            {
                CreateCompetition(competition);
            }
            foreach (var season in data.Seasons)
            {
                CreateSeason(season, season.Competition.CompetitionId.Value);
                foreach (var teamInSeason in season.Teams)
                {
                    AddTeamToSeason(teamInSeason);
                }
            }
            foreach (var tournament in data.Tournaments)
            {
                CreateTournament(tournament);
                foreach (var teamInTournament in tournament.Teams)
                {
                    AddTeamToTournament(teamInTournament, tournament);
                }
                foreach (var season in tournament.Seasons)
                {
                    AddTournamentToSeason(tournament, season);
                }
            }

            var probabilities = new Dictionary <Guid, int>();

            foreach (var match in data.Matches)
            {
                CreateMatch(match);

                var statisticsRecords = _playerInMatchStatisticsBuilder.BuildStatisticsForMatch(match);
                foreach (var record in statisticsRecords)
                {
                    var random = new Random();
                    if (!probabilities.ContainsKey(record.PlayerIdentityId))
                    {
                        probabilities.Add(record.PlayerIdentityId, random.Next(-999, 999));
                    }
                    record.Probability = probabilities[record.PlayerIdentityId];

                    CreatePlayerInMatchStatisticsRecord(record);
                }
            }
        }
        /// <remarks>
        /// https://devblogs.microsoft.com/aspnet/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/
        /// </remarks>
        private async Task <CancellationToken> UpdateStatistics(Guid taskId, Guid memberKey, string memberName, CancellationToken cancellationToken)
        {
            try
            {
                Logger.Info(GetType(), "Updating match statistics for all matches in {Type:l}.{Method:l}.", GetType(), nameof(UpdateStatistics));

                var matchListings = (await _matchListingDataSource.ReadMatchListings(new MatchFilter
                {
                    IncludeMatches = true,
                    IncludeTournamentMatches = true,
                    IncludeTournaments = false,
                    UntilDate = DateTime.UtcNow
                }, MatchSortOrder.MatchDateEarliestFirst).ConfigureAwait(false));

                _taskTracker.SetTarget(taskId, matchListings.Sum(x => x.MatchInnings.Count) + matchListings.Count);

                using (var connection = _databaseConnectionFactory.CreateDatabaseConnection())
                {
                    connection.Open();

                    foreach (var matchListing in matchListings)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            Logger.Warn(GetType(), "Background task cancellation requested in {Type:l}.{Method:l}.", GetType(), nameof(UpdateStatistics));
                        }

                        try
                        {
                            var match = await _matchDataSource.ReadMatchByRoute(matchListing.MatchRoute).ConfigureAwait(false);

                            if (match != null)
                            {
                                using (var transaction = connection.BeginTransaction())
                                {
                                    await _statisticsRepository.DeletePlayerStatistics(match.MatchId.Value, transaction).ConfigureAwait(false);

                                    foreach (var innings in match.MatchInnings)
                                    {
                                        await _statisticsRepository.DeleteBowlingFigures(innings.MatchInningsId.Value, transaction).ConfigureAwait(false);

                                        innings.BowlingFigures = _bowlingFiguresCalculator.CalculateBowlingFigures(innings);
                                        await _statisticsRepository.UpdateBowlingFigures(innings, memberKey, memberName, transaction).ConfigureAwait(false);

                                        _taskTracker.IncrementCompletedBy(taskId, 1);
                                    }

                                    var hasPlayerData = _playerIdentityFinder.PlayerIdentitiesInMatch(match).Any();
                                    if (hasPlayerData)
                                    {
                                        var statisticsData = _playerInMatchStatisticsBuilder.BuildStatisticsForMatch(match);
                                        await _statisticsRepository.UpdatePlayerStatistics(statisticsData, transaction).ConfigureAwait(false);
                                    }
                                    _taskTracker.IncrementCompletedBy(taskId, 1);
                                    transaction.Commit();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(GetType(), "Error '{Error}' updating match statistics for '{MatchRoute}' in {Type:l}.{Method:l}.", ex.Message, matchListing.MatchRoute, GetType(), nameof(UpdateStatistics));
                            _taskTracker.IncrementErrorsBy(taskId, 1);
                        }
                    }

                    using (var transaction = connection.BeginTransaction())
                    {
                        await _statisticsRepository.UpdatePlayerProbability(null, transaction).ConfigureAwait(false);

                        transaction.Commit();
                    }

                    Logger.Info(GetType(), "Completed updating match statistics for all matches in {Type:l}.{Method:l}.", GetType(), nameof(UpdateStatistics));
                }
            }
            catch (TaskCanceledException tce)
            {
                Logger.Error(GetType(), "Caught TaskCanceledException '{Message}' in {Type:l}.{Method:l}.", tce.Message, GetType(), nameof(UpdateStatistics));
            }

            return(cancellationToken);
        }