2014-02-06 72 views
3

我有一個簡單的模型,當我在調試器中運行網站時,實體框架沒有正確填充模型。未填充的實體框架子對象

的模式很簡單:

public class Team 
{ 
    /// <summary> 
    ///  Constructor required for the EntityFramework to create the object. 
    /// </summary> 
    private Team() 
    {    
    } 

    public Team(string name, ApplicationUser owner) 
    { 
     Name = name; 
     Owner = owner; 
    } 

    [Required] 
    public int Id { get; private set; } 

    [Required] 
    public string Name { get; private set; } 

    [Required] 
    public ApplicationUser Owner { get; private set; } 

    [Required] 
    public List<TeamMembership> Members { get; set; } 
} 


public class TeamMembership 
{ 
    /// <summary> 
    ///  Constructor for the EntityFramework 
    /// </summary> 
    private TeamMembership() 
    { 
    } 

    public TeamMembership(ApplicationUser user, MembershipStatus status) 
    { 
     User = user; 
     Status = status; 
    } 

    [Required] 
    public ApplicationUser User { get; private set; } 

    [Required] 
    public MembershipStatus Status { get; set; } 

    [Required] 
    public int Id { get; private set; } 
} 

ApplicationUser是由ASP MVC 5成員基礎設施生成的默認類。

當我運行我的測試(Specflow),它爲每個測試創建一個具有唯一ID的新LocalDb數據庫,並在該數據庫上運行遷移時,實體框架將正確填充我的團隊和所有者。

但是,當我運行網站並嘗試與應用程序進行交互時,我的團隊未完全填充,因爲所有者爲null而且未填充Members。但是,在數據庫中正確設置了所有者ID,查詢似乎沒問題。在測試和應用程序運行期間執行的查詢看起來是一樣的。

爲什麼會這樣,我該如何開始調試該問題?

我覺得我缺少一些簡單的東西。

回答

8

你可能需要添加.Include()到您的查詢,這是不是你的問題顯示,但應該是這個樣子:

var query = context.Teams.Include(x => x.Owner).Include(x => x.Members).Where(...); 

EF只會加載頂級的實體,而不是由它引用的實體直到需要它們(延遲加載)。如果你還沒有處理上下文,試圖訪問這些導航屬性應該使它們從數據庫中加載,但是如果上下文已經被處理,這不會發生。

.Include()將通知EF,這些導航屬性需要與引用實體一起被急切加載。

查看this MSDN page瞭解更多關於lazy/eager加載和如何控制它的細節。

+0

謝謝史蒂夫。這確實似乎解決了這個問題。然而,我有點困惑,爲什麼我的集成測試(調用控制器上的方法)工作並具有完整的填充對象。這是由於上下文的生命週期嗎?我認爲我的測試爲測試的生命週期創建了一個上下文,這可能是幾個控制器方法調用,並且在IIS中運行時,SimpleInjector將爲每次調用創建一個DBContext。但是,在加載團隊和瀏覽所有者/成員之間不應該放置dbcontext –

+0

如果上下文尚未處理(並且實體仍附加到上下文中),並且您訪問導航屬性,則EF應擊中數據庫再次抓取該實體。如果上下文被處置,這不會發生。我將添加一個鏈接到答案的更多信息。 – Steve

+0

實體是否仍會附加到上下文,除非它已明確分離? –