I have classes like:
Person
{
Name
Address
}
Employee : Person
{
Compensation - object
}
Visitor : Person
{
}
If I write linq:<
This horrible thing works:
var persons = context.Persons
.Concat(context.Employees
.Where(e => e.Compensation.Amount >= 0))
.Concat(context.Visitors
.Where(v => v.SomeProperty == "AlwaysTrue"));
I'm not sure why, but when you filter on an object property, the property's object is eagerly loaded. If you don't want to filter that property, then use a condition that will always be true.
Disclaimer: I have no idea how efficient the resulting query is. I checked the sql generated when I tested this in a slightly more complicated scenario and it was very very large.
You can try it this way:
var persons = Context.Persons
.OfType<Employee>()
.Include("Compensation")
.Concat<Person>(Context.Persons.OfType<Visitor>());
Here's a nice example of how to load Persons
and include Compensation
for Employees
Replace Reference()
by Collection()
for a collection property.
IQueryable<Person> GetPersons()
{
var persons = Context.Persons;
foreach(var entry in persons.OfType<Employee>())
Context.Entry(entry).Reference(e => e.Compensation).Load();
return persons;
}
Not sure either if it's efficient, but it works, and the intention is clearer than with joins.
Based on this SO answer
var employees = context.Persons.OfType<Employee>().Include(x => x.Compensation).ToArray();
var nonEmployees = context.Persons.Except(context.Persons.OfType<Employee>()).ToArray();
var people = employees.Concat(nonEmployees);