I have an application that allows a user to create a poll that includes questions and answer choices as part of the poll. The hierarchy is a poll has one or more questions, a question has one or more answers, and each answer has a vote.
The following code is my implementation that allows the updating of an existing poll. The update allows for properties of the poll to be updated, including the addition or removal of children.
The implementation works, but it feels like there is a better way to achieve the functionality. As you will see from my code, I'm creating a context object each time I want to add or update any of the objects.
public string Update(Poll poll)
{
try
{
if (poll == null)
return null;
using (var context = new PollContext())
{
context.Entry(poll).State = poll.PollId == Guid.Empty ? EntityState.Added : EntityState.Modified;
context.Polls.AddOrUpdate(poll);
context.SaveChanges();
}
//update the questions
using (var context = new PollContext())
{
foreach (var question in poll.Questions)
{
context.Entry(question).State =
question.QuestionId == Guid.Empty ? EntityState.Added : EntityState.Modified;
context.Questions.AddOrUpdate(question);
}
context.SaveChanges();
}
//update the answers
using (var context = new PollContext())
{
foreach (var answers in poll.Questions.Select(question => question.Answers).ToList())
{
var questionId = answers.ElementAt(0).QuestionId;
var originalAnswerList = GetOriginalAnswerList(questionId);
using (var context2 = new PollContext())
{
foreach (var originalAnswer in originalAnswerList)
{
if (answers.All(a => a.AnswerId != originalAnswer.AnswerId))
{
Delete(originalAnswer);
Delete(originalAnswer.Votes);
}
}
}
foreach (var answer in answers)
{
context.Entry(answer).State =
answer.AnswerId == Guid.Empty ? EntityState.Added : EntityState.Modified;
context.Answers.AddOrUpdate(answer);
context.Votes.AddOrUpdate(answer.Votes);
}
}
context.SaveChanges();
}
return "Poll updated";
}
catch (NullReferenceException ex)
{
throw new NullReferenceException("A null exception occurred in updating poll.\r\n" + ex.InnerException);
}
catch (Exception ex)
{
throw new Exception("An exception occurred in the updating poll.\r\n" + ex.InnerException);
}
}