2009-07-21 126 views
3

我已經得到了(大大簡化)的EF層次看起來是這樣的:包括實體框架TPH類導航屬性

class Room { EntityCollection<Session> Sessions; } 
class Session { EntityCollection<Whiteboard> Whiteboards; EntityReference Room; } 
class Whiteboard { EntityCollection<WhiteboardShape> WhiteboardShapes; EntityReference Session; } 
abstract class WhiteboardShape { EntityReference Whiteboard; } 
class WhiteboardShapeEllipse : WhiteboardShape { } 
class WhiteboardShapePolyline { WhiteboardShape { EntityCollection<PolylinePoint> PolylinePoints } 
class PolylinePoint { EntityReference<WhiteboardShapePolyline> WhiteboardShapePolylineReference; } 

換句話說,一個房間可以包含多個會話;每個會話可以包含多個白板;並且每個白板可以包含多個白板形狀。這些形狀可以有多種類型,包括一個WhiteboardShapePolyline,它本身可以包含多個PolylinePoints。

當一個遠程用戶最初連接到房間,我需要將整個對象圖傳遞給用戶,並且我試圖找出如何從數據庫圖表加載到內存中儘可能有效地。

現在,當然,在EF允許你做預先加載,就像這樣:

 Room room = ctx.Room 
      .Include("Sessions.Whiteboards") 
      .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName); 

,但包括()不會讓我加載了PolylinePoints。特別是,如果我嘗試:

 Room room = ctx.Room 
      .Include("Sessions.Whiteboards.WhiteboardShape.PolylinePoint") 
      .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName); 

我得到的異常「A指定包含路徑是無效的的EntityType‘SlideLinc.Model.WhiteboardShape’沒有聲明名稱爲‘PolylinePoint’導航屬性。」

也不這項工作:

.Include("Sessions.Whiteboards.WhiteboardShapePolyline.PolylinePoint") 

也沒有這樣的:

.Include("Sessions.Whiteboards.WhiteboardShape.WhiteboardShapePolyline.PolylinePoint") 

取景也不是我能想到的導航路徑的任何其他方式。

,我已經結束了做的方式,確保似乎就像一個黑客對我說:

 // 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(); } 
         } 
        } 
       } 
      } 
     } 

它的工作原理,但它比我想了很多更多的代碼,它是一大堆更多數據庫訪問比我想要的。

我發現的最接近的答案是here,但是我可憐的Linq餓死的大腦無法弄清楚如何將示例代碼轉換爲我所擁有的更復雜的層次結構;此外,該鏈接的示例代碼非常難看,難以理解。我真的不希望我的整個對象層次取決於如何EF在內部構造的層次結構的模糊和不可見的副作用。

其他建議?

回答

3

我可能會使用投影此。不是返回實體類型,而是投影到輕量級數據傳輸對象或匿名類型。當你的項目(例如,使用LINQ查詢),裝載自動發生。在這種情況下,您不需要指定Include。

0

我只是有類似的問題給你(更容易naviagation路徑),我意識到,屬性名在Designer.cs文件不是我的預期。一旦我將它更改爲設計器文件中的PropertyName,它一切正常 - 也注意到我做了兩條不同的路徑,它們變成了:

.Include("UnexpectedNameA").Include("UnexpectedNameB")