views:

772

answers:

2

Assume the following hierarchy:

class Department { EntityCollection<Employee> Employees; }

class Employee { string Name; }

class RemoteEmployee : Employee { Country Location; EntityReference<Country> CountryReference; }

So, department contains a list of employees. There is a hierarchy of employee types, some types reference other entities. Let's suppose we need to load department with its employees. OK, not a problem:

dataContext.Departments.Include("Employees")

This returns concrete employee types (i.e. RemoteEmployee for Remote ones). Now we need to load Location with Remote employees.

dataContext.Departments.Include("Employees").Include("Employees.Location") - Error: no such property in Employee
dataContext.Departments.Include("Employees").Include("RemoteEmployees.Location") - Error: no such property in Department

What should I specify in Include to load Location with RemoteEmployee?

A: 

You got it wrong. All you need to do is:

dataContext.Departments.Include("Employees.Location")
dataContext.Departments.Include("RemoteEmployees.Location")

This will also load the related RemoteEmployees and Employees collections.

mhenrixon
+2  A: 

I'm pretty sure what CatZ suggests doesn't work.

I don't think you can do this using Include, but you can achieve the same effect using a projection trick see this How to Sort Relationships in the Entity Framework

What you need to do is something like this:

var results = from d in ctx.Departments
              select new {
                   d, 
                   employees = d.Employees.Select(
                      e => new {
                          e, 
                          location = e is RemoteEmployee ? 
                                     (e as RemoteEmployee).Location : 
                                     null
                     }
                   )
              };


foreach (var result in results)
{
    var re = result.d.Employees.First() as RemoteEmployee;
    Console.WriteLine("{0} {1} works from {2}", 
           re.Firstname, re.Surname, re.Location.Name);
}

Notice that you don't need to use the anonymous types to get the data, essentially doing the projection has a side-effect of filling the collections on you department because of a feature of the Entity Framework called fixup.

Hope this helps Alex

Alex James
Thanks, that helps. I can't say I'm happy with this solution.Now I just manually load required properties using this:department.Employees.OfType<RemoteEmployee>.ForEach(re => re.LocationReference.Load());It seems like more readable but at the speed cost.
Rouslan Minasian
@Alex I am trying to implement the above solution, but in the above example where you have `d.Employees.Select(` my navigation property is not a collection because of the multiplicity, so it does not have a Select( method. If it was instead a single employee like `d.Employee` and I wanted to check and see if Employee was a certain derived type, and if so then load it's navigation properties.
AaronLS