// These methods are not static, as they need the DbContext to pull in data for mapping. public Survey ConvertToEntity(SurveyModel model) { Survey survey = _db.Surveys.Where(s => s.Description == model.Description).SingleOrDefault(); if (survey == null) { survey = new Survey() { SurveyQuestions = new List <SurveyQuestion>() }; _db.Surveys.Add(survey); } // For now, ignore ID - assume is new. We can delete existing if re-importing. survey.Name = model.Name; survey.Description = model.Description; survey.IntroText = model.IntroText; survey.LastUpdated = DateTimeOffset.Now; survey.Version += 1; // Map the provided IDs to the existing or db-generated questions, to preserve navigation mapping Dictionary <int, Question> questionsByModelID = new Dictionary <int, Question>(); Dictionary <int, AnswerChoice> answerChoicesByModelID = new Dictionary <int, AnswerChoice>(); // Process all questions and answer choices first, so we have them in the db and indexed by model ID. foreach (SurveyQuestionModel qm in model.Questions) { // See if question already exists. Remember, questions are reusable, and can be shared across surveys. Question q = _db.Questions.WhereEx(eq => eq.QuestionText == qm.QuestionText).SingleOrDefault(); if (q == null) { q = new Question(); _db.Questions.Add(q); Trace.WriteLine($"+ Q {q.QuestionText}"); } else { Trace.WriteLine($"- Q {q.QuestionText}"); } q.QuestionText = qm.QuestionText; q.ClarificationText = qm.QuestionHelpText; // Move to SurveyQuestion? q.AllowMultipleAnswers = qm.AllowMultipleAnswers; // Move to SurveyQuestion? q.WellKnownQuestion = qm.WellKnownQuestion; questionsByModelID.Add(qm.QuestionID, q); foreach (SurveyQuestionAnswerChoiceModel acm in qm.AnswerChoices) { // See if answer choice already exists. Remember, answer choices are reusable, and can be shared across questions and surveys. AnswerChoice a = _db.AnswerChoices.WhereEx(ac => ac.AnswerText == acm.AnswerChoiceText && ac.AdditionalAnswerDataFormat == acm.AdditionalAnswerDataFormat).SingleOrDefault(); if (a == null) { a = new AnswerChoice(); _db.AnswerChoices.Add(a); Trace.WriteLine($" + AC {a.AnswerText}"); } else { Trace.WriteLine($" - AC {a.AnswerText}"); } a.AnswerText = acm.AnswerChoiceText; a.AdditionalAnswerDataFormat = acm.AdditionalAnswerDataFormat; if (!answerChoicesByModelID.ContainsKey(acm.AnswerChoiceID)) { answerChoicesByModelID.Add(acm.AnswerChoiceID, a); } } } // Now we can process the model into the survey-specific entities. // TODO: This block can now be moved into previous foreach (SurveyQuestionModel qm in model.Questions) { Question q = questionsByModelID[qm.QuestionID]; SurveyQuestion sq = survey.SurveyQuestions.Where(sq2 => sq2.Question == q).SingleOrDefault(); if (sq == null) { sq = new SurveyQuestion { Question = q, AnswerChoices = new List <SurveyAnswerChoice>() }; survey.SurveyQuestions.Add(sq); _db.SurveyQuestions.Add(sq); } sq.QuestionNum = qm.QuestionNum; } // Finally, with the SurveyQuestions all added and mapped, we can process AnswerChoices with forward-referenced NextQuestionID nav property foreach (SurveyQuestionModel qm in model.Questions) { Question q = questionsByModelID[qm.QuestionID]; SurveyQuestion sq = survey.SurveyQuestions.Where(sq2 => sq2.Question == q).SingleOrDefault(); foreach (SurveyQuestionAnswerChoiceModel acm in qm.AnswerChoices) { // See if survey answer choice already exists. SurveyAnswerChoice sac = sq.AnswerChoices.Where(c => c.AnswerChoice == answerChoicesByModelID[acm.AnswerChoiceID]).SingleOrDefault(); if (sac == null) { sac = new SurveyAnswerChoice { AnswerChoice = answerChoicesByModelID[acm.AnswerChoiceID], }; sq.AnswerChoices.Add(sac); _db.SurveyAnswerChoices.Add(sac); } sac.AnswerChoiceNum = acm.AnswerChoiceNum; if (acm.NextQuestionID.HasValue && acm.NextQuestionID.Value != -1) { try { sac.NextSurveyQuestion = survey.SurveyQuestions.Where(ssq => ssq.Question == questionsByModelID[acm.NextQuestionID.Value]).Single(); } catch (Exception ex) { throw new InvalidOperationException($"Couldn't find NSQ {acm.NextQuestionID} (Q='{q.QuestionText}', AC='{acm.AnswerChoiceText}')", ex); } } else if (acm.NextQuestionID.HasValue && acm.NextQuestionID.Value == -1) { sac.EndSurvey = true; } } } return(survey); }
public static SurveyResponseModel GenerateRandomResponseForSurvey(Survey Survey) { var Addr = Generator.GenerateAddress(); SurveyResponseModel Responses = new SurveyResponseModel() { StartTime = DateTime.Now.AddMinutes(-7), EndTime = DateTime.Now, GPSLocation = new PITCSurveyLib.GPSLocation() { Lat = 47.6419587, Lon = -122.1327818, Accuracy = 0 }, NearestAddress = new PITCSurveyLib.Address() { Street = Addr.AddressLine, City = Addr.City, State = Addr.StateAbbreviation, ZipCode = Addr.ZipCode }, LocationNotes = "", SurveyID = 1, Survey_Version = Survey.Version, ResponseIdentifier = Guid.NewGuid(), }; foreach (var Question in Survey.SurveyQuestions) { var Response = new SurveyQuestionResponseModel() { QuestionID = Question.ID }; int AnswersToSelect = Question.Question.AllowMultipleAnswers ? Rnd.Next(1, Question.AnswerChoices.Count() / 4) : 1; for (int i = 0; i < AnswersToSelect; i++) { SurveyAnswerChoice Choice = Question.AnswerChoices[i]; SurveyQuestionAnswerChoiceResponseModel Answer = new SurveyQuestionAnswerChoiceResponseModel() { QuestionID = Question.Question.ID, AnswerChoiceID = Choice.AnswerChoice.ID }; switch (Choice.AnswerChoice.AdditionalAnswerDataFormat) { case PITCSurveyLib.AnswerFormat.Int: Answer.AdditionalAnswerData = Ints().ToString(); break; case PITCSurveyLib.AnswerFormat.Date: Answer.AdditionalAnswerData = Dates().ToShortDateString(); break; case PITCSurveyLib.AnswerFormat.String: if (Question.Question.WellKnownQuestion == PITCSurveyLib.WellKnownQuestion.NameOrInitials) { Answer.AdditionalAnswerData = Names(); } else { Answer.AdditionalAnswerData = Words(); } break; default: break; } Response.AnswerChoiceResponses.Add(Answer); } Responses.QuestionResponses.Add(Response); } return(Responses); }