Why does LINQ query throw an exception when I attempt to get a count of a type
Solution 1
The exception is thrown at the Count() statement because LINQ uses deferred execution and the actual LINQ query will not be executed until to call .Count()
, .ToList()
, etc.
Solution 2
This looks like a normal null reference exception in linq2objects while it tries to execute your predicates or projections.
The cases were you'd get a null ref exception that I can think of are if some elements of the "somedata" collection are null, if "h.Year" is null (what type is that?), or if "p.somemoredate" is null..
Solution 3
Deferred execution strikes again!
(First off, my first guess is that this is caused by p.somemoredate being null somewhere in your collection.)
Given your example, there's no way for us to really know, since you've simplified away the bits that are being queried. Taking it at its face, I would say that whatever "somedata" or "somemoredate" are the things you need to look at.
To figure this out, (when I get really desperate) I split the query into parts and watch where exceptions get thrown. Notice the .ToArray() calls which will basically "stop" deferred execution from happening temporarily:
var sd = somedata.ToArray();
var x = (from p in sd from h in p.somemoredate.ToArray()).ToArray(); //My guess is that you'll get your exception here.
Broken up like this, it's a lot easier to see where the exception gets thrown, and where to look for problems.
Solution 4
I ran into the same issue. It is annoying that MS did not provide built-in null detection and handling for the aggregate functions. The other issue is I wanted to ensure I got a 0 or $0 return result for nulls/empty query results, as I was working on dashboards/reporting. All of those tables would have data eventually, but early on you get a lot of null returns. After reading multiple postings on the subject I came up with this:
Retrieve the fields you want to return or later apply aggregate functions to first. Test for a null return. Return 0 if a null is detected.
If you do get actual data returned then you can safely utilize/apply the Count or Sum aggregate Linq functions.
public ActionResult YourTestMethod()
{
var linqResults = (from e in db.YourTable
select e.FieldYouWantToCount);
if (linqResults != null)
{
return Json(linqResults.ToList().Count(), JsonRequestBehavior.AllowGet);
}
else
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}
Sum Example Below
public ActionResult YourTestMethod()
{
var linqResults = (from e in db.YourTable
select e.Total);
if (linqResults != null)
{
return Json(linqResults.ToList().Sum(), JsonRequestBehavior.AllowGet);
}
else
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}
thenth
Updated on August 29, 2020Comments
-
thenth over 3 years
public readonly IEnumerable<string> PeriodToSelect = new string[] { "MONTH" }; var dataCollection = from p in somedata from h in p.somemoredate where h.Year > (DateTime.Now.Year - 2) where PeriodToSelect.Contains(h.TimePeriod) select new { p.Currency, h.Year.Month, h.Value };
Can someone tell me why an exception is thrown when at the following line of code?
int count = dataCollection.Count();
This is the exception:
System.NullReferenceException: Object reference not set to an instance of an object. at System.Linq.Enumerable.<SelectManyIterator>d__31`3.MoveNext() at System.Linq.Enumerable.<SelectManyIterator>d__31`3.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at ...
-
thenth over 13 yearsThank you. So this means that there is an actual error occurring in the Linq query itself?
-
Stefanvds over 13 yearsno it means that you didnt ask the count to an IEnuberable, you just forgot the .ToList()
-
Albin Sunnanbo over 13 years@Stefanvds: no it is very much OK to call the Count() method on the resulting IQueryable<T>/IEnumerable<T> without calling .ToList() first.
-
thenth over 13 yearsUnfortunately, the exception is still thrown when I convert to a list?
-
Alex Humphrey over 13 years+1: Unless we get more information, this is the most likely cause. I meant to say
someData
rather thandataCollection
in my comment on the question :). -
Martin about 13 yearsThis is the correct answer ... funny, I already upvoted Albin's comment on the question a LONG time ago.
-
Ciccio about 9 yearsThe problem is that you have one of your property NULL, so when it tries to do a comparison the exception is thrown... the comparison is performed on
Contains
... but just when you do.Count()
you really retrieve the result of the linq query.. -
eidylon about 2 yearsI don't think adding default null handling would really work, because in different situations you might want to treat nulls differently. Sometimes you might want to exclude them, other times you might want to NVL/IsNull them with a default value. The compiler can't know what your business logic needs to be.