-2

I faced this problem and found no solutions online. So I hope to document my situation and my finding here for others who might face a similar problem.

This is not a duplicate of all the other LINQ and Null Reference questions. I read those while researching this, and my situation was not ignorance of LINQ, nor ignorance of OOP. It was the fact that two different environments were pointing me to the wrong data point.

This is my distillation of a pretty complex LINQ query to hit a SQL Server database.

var query = from i in db.Items
            join s in db.Stores on i.Id equals s.ItemId
            from c in db.Sets.Where(t => t.ChildItemId == i.Id && t.StoreId = s.Id).DefaultIfEmpty()
            from a in db.Attributes.Where(a => a.ItemId == c.ChildItemId).DefaultIfEmpty()
            where i.IsActive && s.IsActiveAtStore
            select new
            {
                Id = c != null ? c.ParentItemId : i.Id,
            }
            ...

N.b. The left joins.

The (actual) LINQ compiles. It also correctly and successfully queries the database.

But my task was to unit test this query with object data. When I ran the unit tests, they kept failing at the Attributes clause:

from a in db.Attributes.Where(a => a.ItemId == c.ChildItemId).DefaltIfEmpty()

Visual Studio complained Reference not set to an instance of an object. This query is actually pretty big, and, of course, impossible to debug. So I mocked it up in LinqPad, and it said the same thing. What it added was that a was the problem. That is, the squiggly indicating the error was under the first a in (a => a.ItemId...). But this a can never be null. If it's null, then there's nothing in db.Attributes, and the Where will not run the anonymous function. How the heck was a null?

Jeff Maner
  • 1,179
  • 9
  • 23

1 Answers1

0

I finally realized that I was being misdirected. a was not null, in spite of what the debugger was saying. c was null. It's a simple problem and a simple fix:

from a in db.Attributes.Where(a => c != null ? a.ItemId == c.ChildItemId : false).DefaultIfEmpty()

I hope this helps others in the future avoid h>1 hours of confusion due to error message misdirection. You can't always trust the debugger or the error message.

Jeff Maner
  • 1,179
  • 9
  • 23