public virtual void OnCopyingRace(Distance distance, Race original, Race copy, RacesCopySettings settings)
 {
 }
        public async Task CopyRacesAsync(Distance sourceDistance, Distance destinationDistance, RacesCopySettings settings)
        {
            Debug.Assert(sourceDistance.Races != null, "sourceDistance.Races != null");
            Debug.Assert(destinationDistance.Races != null, "destinationDistance.Races != null");

            var expert = distanceExpertManager.Find(destinationDistance.Discipline);

            using (var transaction = context.UseOrBeginTransaction(IsolationLevel.RepeatableRead))
                try
                {
                    var oldRaces = destinationDistance.Races.ToList();
                    foreach (var race in oldRaces)
                    {
                        context.Races.Remove(race);
                    }
                    await context.SaveChangesAsync();

                    var heatDiff = destinationDistance.FirstHeat - sourceDistance.FirstHeat;
                    foreach (var race in sourceDistance.Races)
                    {
                        var newRace = new Race
                        {
                            Id           = Guid.NewGuid(),
                            Distance     = destinationDistance,
                            Round        = race.Round,
                            Heat         = race.Heat + heatDiff,
                            Lane         = race.Lane,
                            Color        = race.Color,
                            Competitor   = race.Competitor,
                            Transponders = settings.CopyTransponders
                                ? race.Transponders?.Select(rt => new RaceTransponder
                            {
                                PersonId = rt.PersonId,
                                Type     = rt.Type,
                                Code     = rt.Code,
                                Set      = rt.Set
                            }).ToList()
                                : null
                        };
                        await UpdateCompetitorBestTimesAsync(destinationDistance, newRace);

                        expert?.OnCopyingRace(destinationDistance, race, newRace, settings);
                        destinationDistance.Races.Add(newRace);
                    }

                    await context.SaveChangesAsync();

                    transaction.Commit();

                    if (oldRaces.Any())
                    {
                        recorder.RecordEvent(new DistanceRacesDeletedEvent(destinationDistance, oldRaces));
                    }
                    recorder.RecordEvent(new DistanceRacesAddedEvent(destinationDistance, destinationDistance.Races));
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
        }