I'm using LINQ to Entities to get some data from a database. Below is my query.
var location = from l in dbContext.Locations
join e in dbContext.Equipment on l.ID equals e.LocationID into rs1
from e in rs1.DefaultIfEmpty()
where ids.Contains(l.ID)
select new
{
EquipmentClass = e,
LocationID = l.ID,
LocationName = l.Name,
EquipmentName = e == null ? null : e.Name,
Description = e == null ? null : e.Description,
InServiceStatus = e == null ? false : e.InServiceStatus,
EquipmentType = e.EquipmentType.Name
};
foreach (var item in location)
{
// some logic
}
In the code above, ids
is a list of ints that I pass in to filter the results. When I get the results, I see that one of the return records has a null EquipmentClass
. I had performed some null checking but realized that I forgot to do null checking on one of the properties. Now I would expect to get a null reference exception on EquipmentType = e.EquipmentType.Name
but I don't. To my surprise, it works just fine, and is set to null. My EquipmentClass
has a property type of EquipmentType
, which is another class. EquipmentType
has a Name
property which is a String.
- Why doesn't this throw a null reference exception?
Just as a test, I removed the null check from InServiceStatus = e == null ? false : e.InServiceStatus
and it fails with an invalid operation exception upon running a foreach loop using the query.
- Does this mean that I only need to do null checking on non-nullable values?
Update:
foreach (var item in location)
{
var p = item.EquipmentClass.EquipmentType.Name;
}
Added this right after the query. On the assignment of p, I get a null reference exception. I'm not sure how it even gets that far, as it should fail on the first line of the foreach loop. Without the line declaring variable p, I do not get a null reference exception. If anyone can explain what is happening I would be grateful. Just for reference, the values of item.EquipmentClass
and item.EquipmentType
are both null by the time the foreach loop starts.
Update2: I found this link where it seems that someone has an almost identical issue using LINQ to SQL. I get the gist of the answer but don't fully understand its potential impact on my two questions above.