2010-12-15 98 views
1

我是實體框架的新手。我使用Ninject在MVC中創建了一個多層應用程序。
我在數據庫中有三個表。說表A,表B和表C.實體框架實體沒有顯示相關實體的屬性

Table A has a foreign key relating it to Table B 
Table B has a foreign key relating it to Table C 

Table A => Table B => Table C 

我的應用程序有一個「服務」,將從MVC控制器調用。
該服務充當每個實體(即TableAService,TableBService)的存儲庫,該實體負責從EF DataContext創建,讀取,更新或刪除實體,並且可能對這些實體執行業務邏輯。

在我的MVC控制器中,我提到了相應的服務。例如:

private TableAService _tableAService; 

public TableAController(EFDataContext dataContext) 
{ 
    _tableAService = new TableAService(dataContext); 
} 

public ActionResult Index() 
{ 
    return View(); 
} 

TableAService會是這個樣子:

private EFDataContext _dataContext; 

public TableAService(EFDataContext dataContext) 
{ 
    _dataContext = dataContext; 
} 

public TableA GetById(int tableAId) 
{ 
    _dataContext.TableA.SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

我明白,在這個例子的服務將被緊密地結合到數據源,我的實際執行情況略有不同,但概念是相同的,我有一個dataContext服務,我想從中返回實體。

問題: - 當我在TableAService的GetById方法中時,SingleOrDefault給了我一個TableB導航屬性,它允許我訪問所有TableB的屬性,包括TableC導航屬性。

但是,當我將TableA傳遞迴控制器時,我無法訪問TableB的任何屬性。

中的服務我也試過:

private ObjectSet<TableA> _objSet = _dataContext.CreateObjectSet<TableA>(); 

return _objSet.SingleOrDefault(ta => ta.TableAId == tableAId); 

這似乎並沒有做出能夠對錶B從訪問表C導航屬性有什麼區別表A實體。

任何幫助將不勝感激!

乾杯,

詹姆斯

回答

0

這需要一些挖掘,但我遇到的問題是我的應用程序沒有引用System.Data.Entity。

嚮應用程序添加引用允許我從控制器內訪問相關對象的屬性。

感謝您的答案,他們確實幫助我排除了可能性。我每個人都投了票。

2

試着改變你的GetById方法:

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA.Include("TableB").SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

如果你想要得到的表C記錄爲好,用途:

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA.Include("TableB.TableC").SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

的原因是Entity Framework使用「延遲加載」,這意味着這些東西直到你真的需要它才從數據庫加載。麻煩的是,一旦您退出服務,數據上下文不再存在以獲取表B的記錄。方法Include指示EF立即加載來自相關表的數據。

3

導航屬性的內容只能在活動ObjectContext的範圍內加載。

這是必需的,因爲實際的行將通過往返數據庫獲取。
在你的情況下,你試圖訪問一個導航屬性,ObjectContext用於檢索實體的第一個地方已經被丟棄,連接丟失。

假設你正在使用Entity Framework 4有2個解決問題的對策:

  • 預先加載:相關實體被加載了前面,那是你明確地指示實體框架加載所有相關實體,而它正在檢索查詢的結果。
    這可以通過幾種不同的方式完成:通過在導航屬性中調用ObjectQuery.Include方法或調用Load方法,或者在ObjectContext.LoadProperty方法中將相關實體包括在查詢的投影中。
  • 延遲加載:相關實體是按需加載的,也就是當導航屬性的getter被第一次訪問時。請注意,這仍然必須在ObjectContext的範圍內完成。

在使用Include方法的情況下,預先加載可能是最合適的解決方案:

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA 
     .Include("TableB.TableC") // use dot-notation to specify depth in the object graph 
     .SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

相關資源: