2012-10-07 87 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是可用的,但是如果你在某些场景中不触及属性,那么它们就不会被加载。 –