title: Including navigation properties from Entity Framework TPH classes
body: <p>I've got an EF hierarchy that (dramatically simplified) looks something like this:</p>
  
  <pre><code>class Room { EntityCollection&lt;Session&gt; Sessions; }
  class Session { EntityCollection&lt;Whiteboard&gt; Whiteboards; EntityReference Room; }
  class Whiteboard { EntityCollection&lt;WhiteboardShape&gt; WhiteboardShapes; EntityReference Session; }
  abstract class WhiteboardShape { EntityReference Whiteboard; }
  class WhiteboardShapeEllipse : WhiteboardShape { }
  class WhiteboardShapePolyline { WhiteboardShape { EntityCollection&lt;PolylinePoint&gt; PolylinePoints }
  class PolylinePoint { EntityReference&lt;WhiteboardShapePolyline&gt; WhiteboardShapePolylineReference; }
  </code></pre>
  
  <p>In other words, a Room can contain multiple sessions; each Session can contain multiple Whiteboards; and each Whiteboard can contain multiple WhiteboardShapes.  These shapes can be of various types, including a WhiteboardShapePolyline, which itself can contain multiple PolylinePoints.</p>
  
  <p>When a remote user initially connects to the room, I need to pass the entire object graph to that user, and I'm trying to figure out how to load that graph from the database into memory as efficiently as possible.</p>
  
  <p>Now, of course, the EF allows for you to do eager loading, like so:</p>
  
  <pre><code>      Room room = ctx.Room
              .Include("Sessions.Whiteboards")
              .FirstOrDefault(r =&gt; r.OwnerID == ownerUserID &amp;&amp; r.Name == roomName);
  </code></pre>
  
  <p>But Include() doesn't let me load up the PolylinePoints.  Specifically, if I try:</p>
  
  <pre><code>        Room room = ctx.Room
              .Include("Sessions.Whiteboards.WhiteboardShape.PolylinePoint")
              .FirstOrDefault(r =&gt; r.OwnerID == ownerUserID &amp;&amp; r.Name == roomName);
  </code></pre>
  
  <p>I get the exception "A specified Include path is not valid. The EntityType 'SlideLinc.Model.WhiteboardShape' does not declare a navigation property with the name 'PolylinePoint'."  </p>
  
  <p>Nor does this work: </p>
  
  <pre><code>.Include("Sessions.Whiteboards.WhiteboardShapePolyline.PolylinePoint")
  </code></pre>
  
  <p>Nor does this:</p>
  
  <pre><code>.Include("Sessions.Whiteboards.WhiteboardShape.WhiteboardShapePolyline.PolylinePoint")
  </code></pre>
  
  <p>Nor any other way of framing the navigation path that I can think of.</p>
  
  <p>The way that I've ended up doing it sure <i>seems</i> like a hack to me:</p>
  
  <pre><code>        // Make sure we've got everything loaded.
          if (room != null)
          {
              if (!room.Sessions.IsLoaded) { room.Sessions.Load(); }
              foreach (Session session in room.Sessions)
              {
                  if (!session.Whiteboards.IsLoaded) { session.Whiteboards.Load(); }
                  foreach (Whiteboard whiteboard in session.Whiteboards)
                  {
                      if (!whiteboard.WhiteboardShape.IsLoaded) { whiteboard.WhiteboardShape.Load(); }
                      foreach (WhiteboardShape shape in whiteboard.WhiteboardShape)
                      {
                          if (shape is WhiteboardShapePolyline)
                          {
                              WhiteboardShapePolyline polyline = (WhiteboardShapePolyline)shape;
                              if (!polyline.PolylinePoints.IsLoaded) { polyline.PolylinePoints.Load(); }
                          }
                      }
                  }
              }
          }
  </code></pre>
  
  <p>It works, but it's a lot more code than I want, and it's a whole bunch more database accesses than I want.  </p>
  
  <p>The closest answer I've found is <a href="https://stackoverflow.com/questions/944332/entity-framework-inheritance-and-include">here</a>, but my poor Linq-starved brain can't figure out how to translate the example code into the more complicated hierarchy that I've got; plus, the sample code at that link is damned ugly and difficult to understand.  I don't really want my entire object hierarchy depending on an obscure and invisible side-effect of how the EF internally constructs its hierarchies.</p>
  
  <p>Any other suggestions?</p>