问题
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 ...
回答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.
回答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..
回答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.
回答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);
}
}
来源:https://stackoverflow.com/questions/3666979/why-does-linq-query-throw-an-exception-when-i-attempt-to-get-a-count-of-a-type