public async Task <DistanceCombinationCompetitor> AddNewCompetitorAsync(Guid competitorId, Guid distanceCombinationId, int?reserve, DistanceCombinationCompetitorStatus status) { using (var transaction = context.UseOrBeginTransaction(IsolationLevel.RepeatableRead)) try { var competitor = await context.Competitors.FirstOrDefaultAsync(c => c.Id == competitorId); if (competitor == null) { throw new CompetitorNotFoundException(); } var combination = await context.DistanceCombinations.FirstOrDefaultAsync(c => c.Id == distanceCombinationId); if (combination == null) { throw new DistanceCombinationNotFoundException(); } CategoryFilter.EnsureMatch(combination.CategoryFilter, competitor.Category); ClassFilter.EnsureMatch(combination.ClassFilter, competitor.Class); var combinationCompetitor = new DistanceCombinationCompetitor { DistanceCombination = combination, Competitor = competitor, Reserve = reserve, Status = status }; context.DistanceCombinationCompetitors.Add(combinationCompetitor); await context.SaveChangesAsync(); recorder.RecordEvent(new DistanceCombinationClassificationChangedEvent(combination)); transaction.Commit(); return(combinationCompetitor); } catch { transaction.Rollback(); throw; } }
public async Task UpdateCompetitorAsync(Guid competitionId, Guid competitorId, IReadOnlyCollection <DistanceCombinationCompetitor> competitorCombinations) { using (var transaction = context.BeginTransaction(IsolationLevel.RepeatableRead)) try { var competitor = await context.Competitors.FirstOrDefaultAsync(c => c.Id == competitorId); if (competitor == null) { throw new CompetitorNotFoundException(); } foreach (var combination in await Combinations(competitionId, competitorId).ToListAsync()) { context.DistanceCombinationCompetitors.Remove(combination); } var combinations = (from c in competitorCombinations join dc in await Combinations(competitionId).ToListAsync() on c.DistanceCombinationId equals dc.Id select new { Competitor = c, Combination = dc }).ToList(); foreach (var c in combinations) { CategoryFilter.EnsureMatch(c.Combination.CategoryFilter, competitor.Category); ClassFilter.EnsureMatch(c.Combination.ClassFilter, competitor.Class); c.Competitor.Competitor = competitor; context.DistanceCombinationCompetitors.Add(c.Competitor); if (c.Competitor.Status == DistanceCombinationCompetitorStatus.Withdrawn) { var competitorRaces = await(from r in context.Races where r.Distance.Combinations.Any(dc => dc.Id == c.Combination.Id) && r.CompetitorId == c.Competitor.CompetitorId select r).ToListAsync(); foreach (var race in competitorRaces) { context.Races.Remove(race); } } } if (competitorCombinations.Any(cc => cc.Status == DistanceCombinationCompetitorStatus.Confirmed || cc.Status == DistanceCombinationCompetitorStatus.Withdrawn)) { competitor.Status = CompetitorStatus.Confirmed; } else if (competitorCombinations.All(cc => cc.Status == DistanceCombinationCompetitorStatus.Pending)) { competitor.Status = CompetitorStatus.Pending; } await context.SaveChangesAsync(); foreach (var combination in combinations.Select(c => c.Combination)) { recorder.RecordEvent(new DistanceCombinationClassificationChangedEvent(combination)); } transaction.Commit(); } catch { transaction.Rollback(); throw; } }