'EF Core Add() only adds the last element to an ICollection
I'm trying to add an element to an ICollection object in EF Core 5. But only the last element remains on the list. As an example, When a student submits an answer, I want to add him to the Participants of the exam(A). It works as it should. But when the same person submits another exam(B). His records are lost from the previous exam(A).
Here is my code.
SubmitExam Method in ExamController.cs
[HttpPost("submit")]
public async Task<ActionResult<GetExamDTO>> SubmitExam(GetExamDTO getExamDTO)
{
var username = User.FindFirst(ClaimTypes.Name).Value;
var user = await _userManager.Users
.Where(u => u.UserName == username)
.Include(u => u.ParticipatedExams)
.ThenInclude(er => er.Exam)
.FirstOrDefaultAsync();
if (user == null)
return Unauthorized("Invalid User");
var exam = await _dbContext.Exams
.Where(e => e.Id == getExamDTO.Id)
.Include(e => e.Creator)
.Include(e => e.Participants)
.Include(exam => exam.Questions)
.ThenInclude(question => question.Options)
.AsSplitQuery()
.SingleOrDefaultAsync();
if (exam == null)
return BadRequest("Invalid Exam Id");
if (!exam.SubmissionEnabled)
return BadRequest("Exam is over. You are too late.");
double marksObtained = 0;
double negativeMarksObtained = 0;
for (int i = 0; i != getExamDTO.Questions.Count(); ++i)
{
var question = exam.Questions.ElementAt(i);
if (question.CorrectAnswerText == getExamDTO.Questions[i].ProvidedAnswer.Text)
{
marksObtained += question.Marks;
}
else
{
marksObtained -= exam.NegativeMarks;
negativeMarksObtained -= exam.NegativeMarks;
}
}
var participatedFromExam = exam.Participants.Where(u => u.Id == user.Id)
.SingleOrDefault();
var participatedFromUser = user.ParticipatedExams
.Where(er => er.ExamId == exam.Id)
.SingleOrDefault();
System.Console.WriteLine("Submit" + participatedFromExam);
if (participatedFromExam == null && participatedFromUser == null) // If user sits for the first time, count him as new.
{
exam.Participants.Add(user); // Participants gets empty for every exam except the last submitted one. It fried my brain.
++exam.Attendees;
if (await _dbContext.SaveChangesAsync() > 0)
System.Console.WriteLine("Added submission");
var result = new ExamResult
{
Exam = exam,
Score = marksObtained
};
user.ParticipatedExams.Add(result);
await _userManager.UpdateAsync(user);
}
var examDto = examToDto(exam);
examDto.Participated = true;
examDto.MarksObtained = marksObtained;
examDto.Questions = getExamDTO.Questions;
examDto.NewSubmission = true;
examDto.NegativeMarks = negativeMarksObtained;
return Ok(examDto);
}
EntityUser.cs
public class EntityUser : IdentityUser
{
public ICollection<ExamResult> ParticipatedExams { get; set; }
public DateTime? LastActive { get; set; } = DateTime.UtcNow;
}
Exam.cs
public class Exam
{
public string Title { get; set; }
public Guid Id { get; set; }
public int Attendees { get; set; } = 0;
public string CreatorId { get; set; }
public EntityUser Creator { get; set; }
public DateTime CreatedAt { get; set; }
public int Duration { get; set; }
public double TotalMarks { get; set; }
public double NegativeMarks { get; set; }
public bool SubmissionEnabled { get; set; }
public ICollection<Question> Questions { get; set; }
public ICollection<EntityUser> Participants { get; set; }
}
ExamResult.cs
public class ExamResult
{
public Guid Id { get; set; }
public Exam Exam { get; set; }
public Guid ExamId { get; set; }
public double Score { get; set; }
}
GetExamDTO.cs
public class GetExamDTO
{
public string Title { get; set; }
public Guid Id { get; set; }
public int Attendees { get; set; } = 0;
public string Subject { get; set; }
public string CreatorId { get; set; }
public string Creator { get; set; }
public DateTime CreatedAt { get; set; }
public int Duration { get; set; }
public double TotalMarks { get; set; }
public double MarksObtained { get; set; }
public double NegativeMarks { get; set; }
public bool SubmissionEnabled { get; set; }
public bool Participated { get; set; }
public bool NewSubmission { get; set; }
public List<QuestionDTO> Questions { get; set; }
public List<ParticipantDTO> Participants { get; set; }
}
I will appreciate any help. Thanks in Advance.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
