我正在使用实体框架和Code First来保存我的数据。延迟加载嵌套集
有一个嵌套列表类:
public class AgeGroup
{
public BindingList<WeightGroup> WeightGroups { get; set; }
}
数据库上下文由
public DbSet<AgeGroup> AgeGroups { get; set; }
我创建一个窗口,在这里用户可以修改AgeGroup
S和他们根据WeightGroup
小号。为了绑定ListBox
的ItemsSource
财产的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
而不是BindingList
的WeightGroups
属性。但是这个接口没有插入和删除实体的方法。此外,如果我只是交换类型,甚至不会加载AgeGroups
。
完美,谢谢。你能解释一下,为什么列表必须是虚拟的?顺便说一句,它也可以在没有额外的'DbSet <>'的情况下工作。 –
EF在这种情况下所做的是创建AgeGroup类的子类并在WeightGroups getter中实现延迟加载。非常精彩,因为你的代码总是可以假定WeightGroups是可用的,但是如果你在某些场景中不触及属性,那么它们就不会被加载。 –