Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to eager load with Include() only if not null?

I am trying to do:

var abc = Context.PersonSet.Include(p=>p.Child).ToList();

But not all Persons have a Child. So I get:

Type Error I would like to get all Persons, and if the Child is not null, I want to Include it. It would be also ok to Include Child as null.

like image 624
thestruggleisreal Avatar asked Dec 19 '18 07:12

thestruggleisreal


3 Answers

I don't know why people keep upvoting the solutions like this:

Include(p => p.NavProp ?? new List<NavPropType>())

Because that won't work, that is invalid for 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.

The solution: declare your property with a default value:

public class Foo
{
    public List<Bar> Bars { get; set; } = new List<Bar>();
}

This makes sure Bars won't be null when no related records are found.

like image 198
CodeCaster Avatar answered Nov 14 '22 21:11

CodeCaster


return empty child instead of null

 Context.PersonSet.Include(a => ((a.Child == null) ? new Collection<Child>() : a.Child));
like image 22
RikiF Avatar answered Nov 14 '22 22:11

RikiF


You can use GroupJoin to get all persons and load their children if they have any child: (consider that in this approach you should have DbSet of Children in your context)

Context.PersonSet.GroupJoin(Context.Children, p => p.Id, c => c.PersonId, (p, c) =>
                 new { Person = p, Child = c }).ToList();
like image 29
masehhat Avatar answered Nov 14 '22 22:11

masehhat