Apologies if this is a duplicate or if I just need to RTFM, but I couldn't find a post that exactly answered my question. I feel I'm reinventing the wheel and there must be a better way. MVC4, Entity Framework 5. I'm using LINQ to project a list of entities from my domain into a list of view models, and encountering NULL reference exceptions, in situations where the navigation property points to a single related entity; for navigation properties which are collections a single level deep; then for those where there may be a navigation property that itself has a navigation property (i.e., maybe two levels deep).
It appears to work when I'm pointing to the actual database; I believe this is because my configuration has lazy loading turned on; but then when I write unit tests I'm getting the NULL reference exceptions. I've got a solution but there's a bit of a code smell. I'd like to find a cleaner solution that works in both situations.
Please consider the following code:
var theList = DomainContext.MyParentEntities.Select(g => new SomeViewModelForAList {
SomeStringProperty = g.SingleRelatedEntity.Name,
SomeIntProperty =
g.EntitiesFromSomeOtherTable.Count(x => !x.IsDeleted),
SomeOtherIntProperty =
g.YetAnotherRelatedEntity.YetMoreChildren.Count(x => !x.IsDeleted)
}).ToList();
Now, it's possible that any of the following entities related to MyParentEntities instances could be NULL: "SingleRelatedEntity", "EntitiesFromSomeOtherTable", "YetAnotherRelatedEntity", and/or "YetMoreChildren". Any of those could throw an exception.
I can write all sorts of NULL coalescing code, which works, but appears redundant and ugly. I've also looked at writing extension methods as described here (although Jimmy's post looks a bit old and maybe there's a better way now):
http://lostechies.com/jimmybogard/2009/12/08/linq-query-operators-and-null-lists/
The extension method idea works, and the technique can be adapted to single related entities using generics; here are my attempts to do that:
public static IEnumerable<TSource> NullsToEmpty<TSource>(this IEnumerable<TSource> source)
{
return source ?? Enumerable.Empty<TSource>();
}
// same idea here
public static T NullToEmpty<T>(this T theEntity) where T : EntityBase, new()
{
var retVal = new T();
if (theEntity == null)
{
retVal.Name = "";
}
else
{
retVal = theEntity;
}
return retVal;
}
The code then becomes:
var theList = DomainContext.MyParentEntities.Select(g => new SomeViewModelForAList {
SomeStringProperty = g.SingleRelatedEntity.NullToEmpty().Name,
SomeIntProperty =
g.EntitiesFromSomeOtherTable.NullsToEmpty().Count(x => !x.IsDeleted),
SomeOtherIntProperty =
g.YetAnotherRelatedEntity.NullToEmpty().
YetMoreChildren.NullsToEmpty().Count(x => !x.IsDeleted)
}).ToList();
Again this works but also feels like it's ugly and repetitive. Any suggestions appreciated. Thank you, -dB