Example #1
0
        public async Task <ResponseModel <List <CreateSessionModel> > > Handle(CreateSessionCommand request, CancellationToken cancellationToken)
        {
            var redisKey        = $"SessionsByTenantId{request.TenantId}";
            var newSessions     = new List <Session>();
            var createdSessions = new List <CreateSessionModel>();

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    foreach (var createSessionModel in request.CreateSessionModels)
                    {
                        var newSession = new Session
                        {
                            CreatedBy   = request.CreatedBy,
                            GameId      = createSessionModel.GameId,
                            Name        = createSessionModel.Name,
                            ClassroomId = createSessionModel.ClassroomId
                        };
                        newSessions.Add(newSession);
                    }

                    if (newSessions.Count > 20)
                    {
                        _context.BulkInsert(newSessions);
                    }
                    else
                    {
                        await _context.Sessions.AddRangeAsync(newSessions, cancellationToken);

                        await _context.SaveChangesAsync(cancellationToken);
                    }

                    transaction.Commit();
                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.Sessions
                                                              .AsNoTracking()
                                                              .ToListAsync(cancellationToken),
                                                              cancellationToken);

                    newSessions.ForEach(x =>
                                        createdSessions.Add(new CreateSessionModel(x.Id, x.GameId, x.ClassroomId, x.Name, x.CreatedBy, x.CreatedAt)));
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();

                    throw new ObjectAlreadyExistsException(nameof(Session), ExceptionExtensions.GetExceptionMessage(ex));
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            return(new ResponseModel <List <CreateSessionModel> >(createdSessions));
        }
        public async Task <ResponseModel <List <CreateOptionModel> > > Handle(CreateOptionCommand request, CancellationToken cancellationToken)
        {
            var redisKey       = $"OptionsWithQuestionByTenantId{request.TenantId}";
            var newOptions     = new List <Option>();
            var createdOptions = new List <CreateOptionModel>();

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var currentQuestions = _context.Questions.Where(x => x.TenantId == request.TenantId);

                    foreach (var createOptionModel in request.CreateOptionModels)
                    {
                        var questionIsExist = await currentQuestions
                                              .AnyAsync(x =>
                                                        x.Id == createOptionModel.QuestionId,
                                                        cancellationToken);

                        if (!questionIsExist)
                        {
                            throw new NotFoundException(nameof(Question), createOptionModel.QuestionId);
                        }
                        var newOption = new Option
                        {
                            CreatedBy       = request.CreatedBy,
                            VisibilityOrder = createOptionModel.VisibilityOrder,
                            QuestionId      = createOptionModel.QuestionId,
                            Text            = createOptionModel.Text,
                            IsCorrect       = createOptionModel.IsCorrect
                        };
                        newOptions.Add(newOption);
                    }

                    if (newOptions.Count > 20)
                    {
                        _context.BulkInsert(newOptions);
                    }
                    else
                    {
                        await _context.Options.AddRangeAsync(newOptions, cancellationToken);

                        await _context.SaveChangesAsync(cancellationToken);
                    }

                    transaction.Commit();
                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.Options
                                                              .AsNoTracking()
                                                              .Include(x => x.Question)
                                                              .ToListAsync(cancellationToken),
                                                              cancellationToken);

                    newOptions.ForEach(x => createdOptions.Add(new CreateOptionModel(x.Id,
                                                                                     x.Text,
                                                                                     x.VisibilityOrder,
                                                                                     x.QuestionId,
                                                                                     x.CreatedBy,
                                                                                     x.CreatedAt,
                                                                                     x.IsCorrect)));
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();

                    throw new ObjectAlreadyExistsException(nameof(Option), ExceptionExtensions.GetExceptionMessage(ex));
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            return(new ResponseModel <List <CreateOptionModel> >(createdOptions));
        }