Question

I have an odd linq subquery issue.

Given the following data structure:

Parents            Children
-------            --------
Id                 Id
                   ParentId
                   Location
                   HasFoo

(obviously this is not the real structure, but it's close enough for this example)

I'm able to run this query and get a desired result:

bool b = (from p in Parents
          from c in Children
          where p.Id == 1 && c.ParentId == p.Id && c.Location == "Home"
          select c.HasFoo).SingleOrDefault();

So if there is a child that has the Location "Home" for a Parent of Id 1, I will get that Child's "HasFoo" value, otherwise, I'll get false, which is the "default" value for a bool.

However, if I try and write the query so I have a list of Parent objects, like so:

var parentList = from p in Parents
                 select new ParentObject
                 {
                   ParentId = p.ParentId,
                   HasHomeChildren = p.Children.Count(c => c.Location == "Home") > 0,
                   HasHomeChildrenWithFoo = (from c in p.Children where c.Location == "Home" select c.HasFoo).SingleOrDefault()
                 }

I get the following error when iterating over the list:

The null value cannot be assigned to a member with type System.Boolean which is a non-nullable value type.

I don't see where this "null" value is coming from, however.

Was it helpful?

Solution

I wonder if the compiler is inferring HasHomeChildrenWithFoo to be bool, but then actually casting to a nullable bool (thus messing up your SingleOrDefault call). At any rate, I'd be willing to bet you could fix it with a cast to a nullable type in that final select which you can then manually default to false when null. It'd probably make the error go away, but it's kind of a brute-force kludge.

var parentList = from p in Parents
                 select new ParentObject
                 {
                   ParentId = p.ParentId,
                   HasHomeChildren = p.Children.Any(c => c.Location == "Home"),
                   HasHomeChildrenWithFoo = (from c in p.Children where c.Location == "Home" select (bool?)c.HasFoo) ?? false)
                 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow