/// <summary>
        /// Asynchronously updates the details of an existing ClassSession entity.
        /// </summary>
        /// <param name="id">Id of the ClassSession entity to be updated.</param>
        /// <param name="dto">DTO containing data to be applied to extant entity.</param>
        /// <returns>The updated entity.</returns>
        /// <exception cref="Exception"></exception>
        public async Task <ClassSession> UpdateAsync(int id, ClassSessionDto dto)
        {
            if (dto == null)
            {
                throw new ArgumentNullException(nameof(dto),
                                                "You tried to call the ClassSessionService.UpdateAsync() method without passing it any data (the DTO was null). Please supply a valid ClassSessionDTO.");
            }

            var entity =
                await GetClassSessionByIdAsync(id);

            entity.Date      = dto.Date ?? entity.Date;
            entity.StartTime = dto.StartTime ?? entity.StartTime;
            entity.EndTime   = dto.EndTime ?? entity.EndTime;

            if (dto.StudentClassId != null)
            {
                entity.StudentClass = await GetStudentClassByIdAsync((int)dto.StudentClassId);
            }

            if (dto.StudentIds.Any())
            {
                entity.Students = await MapStudentIdsToStudents(dto.StudentIds);
            }

            await _repositoryWrapper.SaveAsync();

            return(entity);
        }
        public async Task TestUpdateAsyncIdValidDtoValid()
        {
            // Arrange
            var options = TestUtilities.BuildTestDbOptions();

            ClassSession result;

            await using (var context = new ApplicationDbContext(options))
            {
                context.Database.EnsureCreated();

                context
                .ClassSession
                .Add(new ClassSession
                {
                    Id   = 1,
                    Date = new DateTime(2020, 7, 4),
                }
                     );

                context.SaveChanges();

                Assert.Single(context.ClassSession);

                var repoWrapper = new RepositoryWrapper(context);

                var service = new ClassSessionService(repoWrapper);

                var testDto = new ClassSessionDto
                {
                    StudentClassId = 1,
                    Date           = new DateTime(2020, 7, 7)
                };

                // Act
                result = await service.UpdateAsync(1, testDto);
            }

            // Assert
            await using (var context = new ApplicationDbContext(options))
            {
                Assert.NotNull(result);
                Assert.Single(context.ClassSession);
                Assert.Equal(
                    new DateTime(2020, 7, 7),
                    context.ClassSession.First().Date);

                context.Database.EnsureDeleted();
            }
        }
        public async Task TestUpdateAsyncDtoStudentIdsContainingInvalid()
        {
            // Arrange
            var options = TestUtilities.BuildTestDbOptions();

            await using (var context = new ApplicationDbContext(options))
            {
                context.Database.EnsureCreated();

                context.ClassSession.Add(new ClassSession {
                    Id = 1
                });

                context.SaveChanges();

                var repoWrapper = new RepositoryWrapper(context);

                var service = new ClassSessionService(repoWrapper);

                var testDto = new ClassSessionDto
                {
                    StudentIds = new HashSet <int> {
                        666
                    }
                };

                // Act
                async Task TestAction() =>
                await service.UpdateAsync(1, testDto);

                // Assert
                var ex = await Assert.ThrowsAsync <ArgumentOutOfRangeException>(TestAction);

                Assert.Equal(
                    $"No Student matching the supplied Id was found. The Id you supplied was [{testDto.StudentIds.First()}]. (Parameter 'id')",
                    ex.Message);

                context.Database.EnsureDeleted();
            }
        }
        /// <summary>
        /// Asynchronously creates a new ClassSession entity and saves it
        /// to the context.
        /// </summary>
        /// <param name="dto"></param>
        /// <returns>The created ClassSession entity.</returns>
        /// <exception cref="ArgumentException"></exception>
        public async Task <ClassSession> CreateAsync(ClassSessionDto dto)
        {
            if (dto == null)
            {
                throw new ArgumentException("ClassSession DTO cannot be null.");
            }

            var entity = new ClassSession
            {
                Date         = dto.Date ?? new DateTime(),
                StartTime    = dto.StartTime ?? new DateTime(),
                EndTime      = dto.EndTime ?? new DateTime(),
                StudentClass = await GetStudentClassByIdAsync(dto.StudentClassId.GetValueOrDefault()),
                Students     = await MapStudentIdsToStudents(dto.StudentIds)
            };

            _repositoryWrapper.ClassSession.Add(entity);

            await _repositoryWrapper.SaveAsync();

            return(entity);
        }
        public async Task <IActionResult> Post([Bind] ClassSessionDto dto)
        {
            if (!ModelState.IsValid || dto == null)
            {
                return(BadRequest());
            }

            try
            {
                var result =
                    await _classSessionService
                    .CreateAsync(dto);

                return(CreatedAtAction(
                           "Get",
                           new { id = result.Id },
                           result));
            }
            catch (Exception e)
            {
                return(BadRequest(e.Message));
            }
        }