2012-10-07 63 views
0

我正在使用實體框架和Code First來保存我的數據。延遲加載嵌套集

有一個嵌套列表類:

public class AgeGroup 
{ 
    public BindingList<WeightGroup> WeightGroups { get; set; } 
} 

數據庫上下文由

public DbSet<AgeGroup> AgeGroups { get; set; } 

我創建一個窗口,在這裏用戶可以修改AgeGroup S和他們根據WeightGroup小號。爲了綁定ListBoxItemsSource財產的AgeGroups,我加載它們並綁定到Local集:

ctx.AgeGroups.Load(); 
vm.AgeGroups = ctx.AgeGroups.Local; 

到這裏,不加載的WeightGroups,因爲他們不需要。到現在爲止還挺好。

當用戶選擇要修改的AgeGroup時,必須加載其WeightGroups。到現在爲止我不喜歡這樣(在SelectedAgeGroup setter方法):

value.WeightGroups = (from age in ctx.AgeGroups 
         where age.Id == value.Id 
         select age.WeightGroups).Single(); 

然而,這似乎有點笨拙。首先,因爲設置了新的列表而不是填充現有的列表。此外,還有一些行爲是不需要的。這包括例如以下內容:

  • 如果WeightGroup被修改和SaveChanges()被調用時,舊的組仍然存在,並且另外一個新的與所述修改後的值。
  • 如果用戶刪除了SelectedAgeGroup.WeightGroups.Remove(...)SaveChanges()的實體,則刪除的行仍然存在。

我假設,重新加載上面列出的重量組是造成這種情況的原因。

如何在這種情況下正確地使用延遲加載?理想情況下,必要的WeightGroups由框架自動加載。我閱讀了關於使用IQueryable而不是BindingListWeightGroups屬性。但是這個接口沒有插入和刪除實體的方法。此外,如果我只是交換類型,甚至不會加載AgeGroups

回答

1

您應該能夠通過使WeightGroups虛擬解決這個問題,至少如果你正在使用EF 4.1或更高版本...

public class AgeGroup 
{ 
    public virtual BindingList<WeightGroup> WeightGroups { get; set; } 
} 

您還必須包括一個DbSet的背景下。 ..

public DbSet<WeightGroup> WeightGroups { get; set; } 

然後,它會在您觸摸特性,例如在列表中顯示它會自動加載。

+0

完美,謝謝。你能解釋一下,爲什麼列表必須是虛擬的?順便說一句,它也可以在沒有額外的'DbSet <>'的情況下工作。 –

+0

EF在這種情況下所做的是創建AgeGroup類的子類並在WeightGroups getter中實現延遲加載。非常精彩,因爲你的代碼總是可以假定WeightGroups是可用的,但是如果你在某些場景中不觸及屬性,那麼它們就不會被加載。 –