




вернуть пустой дочерний элемент вместо нуля
Context.PersonSet.Include(a => ((a.Child == null) ? new Collection<Child>() : a.Child));
Я предпочитаю этот вариант, а не давать свойству в модели пустую коллекцию по умолчанию, потому что теперь вы все еще можете легко определить, действительно ли у вас есть DB NULL в базе данных.
Исключение не должно происходить из этой строки. Include() должен использовать LEFT JOIN, который делает именно то, о чем вы просите: «Я хотел бы получить всех лиц, и если дочерний элемент не равен нулю, я хочу включить его». Чтобы убедиться в этом, проверьте SQL, созданный из вашего LINQ.
Чтобы устранить проблему, посмотрите на код, который использует результат запроса abc, и посмотрите, правильно ли он обрабатывает коллекцию Child (т. Е. Проверяет, пуста ли коллекция).
Вы можете использовать GroupJoin, чтобы получить всех людей и загрузить их детей, если у них есть дети: (учтите, что в этом подходе у вас должен быть DbSet of Children в вашем контексте)
Context.PersonSet.GroupJoin(Context.Children, p => p.Id, c => c.PersonId, (p, c) =>
new { Person = p, Child = c }).ToList();
+1, поскольку использование GroupJoin (осторожно!) Также дает вам больший контроль над SQL, сгенерированным EF. Простое использование Include () может привести к очень неэффективному SQL.
Я не знаю, почему люди продолжают голосовать за такие решения:
Include(p => p.NavProp ?? new List<NavPropType>())
Поскольку это не сработает, это недопустимо для Include():
InvalidOperationException:
The Include property lambda expression
p => (p.NavProp ?? value(System.Collections.Generic.List'1[NavPropType]))is invalid. The expression should represent a property access:t => t.MyProperty.To target navigations declared on derived types, specify an explicitly typed lambda parameter of the target type, E.g.
(Derived d) => d.MyProperty. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393.
Решение: объявите свою собственность со значением по умолчанию:
public class Foo
{
public List<Bar> Bars { get; set; } = new List<Bar>();
}
Это гарантирует, что Bars не будет null, если никакие связанные записи не найдены.
Хороший ответ, но мне интересно, а что, если у меня завязались отношения?
Вы можете попробовать следующий подход:
var abc = Context.PersonSet.Include(p=>p.Child).Where(p=>p.Child!=null).ToList();
Думаю, эта строка кода как таковая не должна вызывать ошибки. Вы уверены, что ошибка исходит из этой строки? Вы делаете что-нибудь особенное в конструкторе класса Person?