KeeMach KeeMach -4 years ago 116
ASP.NET (C#) Question

Linq query throws NullReferenceException when pulling data from SQLite, why?

I'm trying to pull data from SQLite database with following query:

DateTime Dzien = new DateTime(ticks ?? 0);
var assinged = Data.Tasks.ToList();
var assign = assinged.Where(t => t.AssignedId ==
Data.AssignedTasks.FirstOrDefault(d => d.Date.Date == Dzien.Date).Id).ToList();

But it throws an exception:

NullReferenceException: Object reference not set to an instance of an object.
PiCoreSQLite.Controllers.HomeController+<>c__DisplayClass3_0.b__0(Tasks t) in HomeController.cs, line 37

Data object is a databese contex and Tasks is a DbSet containing Tasks objects.

I tried removing ToList() but then query doesn't return anything. However it does work and returns data when using similiar query in .cshtml view:

var zrobione =
from completed in Model.Item1.Where(t => t.AssignedId ==
Model.Item3.FirstOrDefault(d => d.Date.Date == DateTime.Today).Id)
group completed by completed.Categories;

I tried rewriting query in fluent syntax and it still throws an exception.

My question is: Why is exception thrown and how to fix it?

Answer Source

Why this exception is thrown?

The problem is caused by the following statement:

Data.AssignedTasks.FirstOrDefault(d => d.Date.Date == Dzien.Date)

The FirstOrDefault method returns the first item in the sequence you apply this method that fulfills the predicate you pass in this method in this case, the predicate is the following:

d => d.Date.Date == Dzien.Date

In case of not found any such an item a null is returned (more generally is returned the default value of the type of the object you are looking for. So if you were looking for an int the default value would be the 0. In case of reference type the default value is null).

That being said is pretty evident that a null is returned and then you try to access the Id property of a null reference...Hence you get this error message.

How can we handle this?

One approach it could be the following:

var assign =  assinged.Where(t => t.AssignedId ==
                                     .FirstOrDefault(d => d.Date.Date == Dzien.Date)?.Id ?? -1))

In the above code I have made the assumption that AssignedId takes only positive or zero values. You could handle this appropriately, if that is not the case.

How the above works?

As we have already mentioned FirstOrDefault would return a reference to the first found object that fulfills the predicate you pass or null. So in order we be safe we use the null conditional operator, ?.. If you get any reference other than null you can read safely the Id, otherwise it is meaningless to do so and the result is null. Then you apply the null coalescing operator ??. This operator returns the left hand value when it is different from null otherwise it returns the right hand value.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download