Вопрос

У меня странная проблема с подзапросом linq.

Учитывая следующую структуру данных:

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

(очевидно, это не настоящая структура, но для этого примера она достаточно близка)

Я могу запустить этот запрос и получить желаемый результат:

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();

Таким образом, если есть дочерний элемент, у которого есть местоположение «Домой» для родителя с идентификатором 1, я получу значение «HasFoo» этого дочернего элемента, в противном случае я получу значение false, что является значением «по умолчанию» для логического значения.

Однако, если я попытаюсь написать запрос, чтобы у меня был список родительских объектов, например:

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()
                 }

При переборе списка я получаю следующую ошибку:

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

Однако я не понимаю, откуда взялось это «нулевое» значение.

Это было полезно?

Решение

Интересно, считает ли компилятор HasHomeChildrenWithFoo логическим значением, но затем фактически приводит к логическому значению, допускающему значение NULL (таким образом, портя ваш вызов SingleOrDefault).В любом случае, я готов поспорить, что вы могли бы исправить это с помощью приведения к типу, допускающему значение NULL, в этом окончательном выборе, который затем можно вручную установить по умолчанию на false, когда значение равно нулю.Вероятно, это устранило бы ошибку, но это своего рода грубая сила.

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)
                 }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top