views:

151

answers:

3
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  A: 

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.

Albin Sunnanbo
Thank you. So this means that there is an actual error occurring in the Linq query itself?
thenth
no it means that you didnt ask the count to an IEnuberable, you just forgot the .ToList()
Stefanvds
@tenth: Yes, that is correct.
Albin Sunnanbo
@Stefanvds: no it is very much OK to call the Count() method on the resulting IQueryable<T>/IEnumerable<T> without calling .ToList() first.
Albin Sunnanbo
Unfortunately, the exception is still thrown when I convert to a list?
thenth
+1  A: 

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.

Dave Markle
+1: Unless we get more information, this is the most likely cause. I meant to say `someData` rather than `dataCollection` in my comment on the question :).
Alex Humphrey
+1  A: 

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..

Diego V