0

I have a table of questions and a table of answers

I always need to display the list of questions regardless and there is a corresponsing asnwer, I need to grab that answer (response)

I use the following code

var Questions = db.Questions.Where(x => x.isActive);
var Answers = db.Answers.Where(x => x.AssessmentID == 99);

AssessmentResponseVM model = new AssessmentResponseVM();
foreach (var question in Questions)
{
    AnswerAndQuestions q = new AnswerAndQuestions { };
    q.QuestionText = question.QuestionText;
    q.QuestionID = question.ID;
    q.Response = Answers.Where(a => a.QuestionID == question.ID).SingleOrDefault().Response; <--- throws exception if there is no answer for the question
    model.Questions.Add(q);
}

But get this error

Object reference not set to an instance of an object.

On this line

q.Response = Answers.Where(a => a.QuestionID == question.ID).SingleOrDefault().Response;
totalitarian
  • 3,606
  • 6
  • 32
  • 55
  • 1
    You cannot get the value of a property of an object that is `null` - test for `null` first, and if not, then access the `Response` property –  Nov 12 '16 at 09:14
  • `var answer = Answers.Where(a => a.QuestionID == question.ID).SingleOrDefault(); if (answer != null) { q.Response = answer.Response; }` –  Nov 12 '16 at 23:14
  • @StephenMuecke that is the way I decided to do it – totalitarian Nov 13 '16 at 12:33

3 Answers3

0

change

q.Response = Answers.Where(a => a.QuestionID == question.ID).SingleOrDefault().Response;

to this code

q.Response=Answers.Any(a=>a.QuestionID==question.ID)?Answers.firstOrDefault(a => a.QuestionID == question.ID).Response:new Response();
Salar Afshar
  • 229
  • 1
  • 2
  • 13
  • 'IQueryable' does not contain a definition for 'firstOrDefault' and no extension method 'firstOrDefault' accepting a first argument of type 'IQueryable' could be found (are you missing a using directive or an assembly reference?) – totalitarian Nov 12 '16 at 09:25
  • @totalitarian; then try with singleorDefault() – Salar Afshar Nov 12 '16 at 09:33
0
q.Response = Answers.Any(a => a.QuestionID == question.ID) ? Answers.Where(a => a.QuestionID == question.ID).FirstOrDefault().Response;
0

If you're allowed to use C# 6.0, I would suggest to try new null-conditional operator.

q.Response = Answers.Where(a => a.QuestionID == question.ID).SingleOrDefault()?.Response;

It returns null when Answers.Where(a => a.QuestionID == question.ID).SingleOrDefault() returns default value, which is null.

If you need something else, not null, you can use null-coalescing operator.

q.Response = Answers.Where(a => a.QuestionID == question.ID).SingleOrDefault()?.Response ?? response, what you need;
Yurii N.
  • 5,455
  • 12
  • 42
  • 66