【问题标题】:Lazy load nested set延迟加载嵌套集
【发布时间】:2012-10-07 21:15:21
【问题描述】:

我正在使用带有 Code First 的实体框架来保存我的数据。

有一个带有嵌套列表的类:

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

数据库上下文包括

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

我正在创建一个窗口,用户可以在其中修改AgeGroups 及其对应的WeightGroups。为了将ListBoxItemsSource 属性绑定到AgeGroups,我加载它们并绑定到Local 集:

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

到目前为止,WeightGroups 没有加载,因为它们不是必需的。到目前为止,一切顺利。

当用户选择一个AgeGroup 进行修改时,它的WeightGroups 必须被加载。到目前为止,我是这样做的(在 SelectedAgeGroup 属性的设置器中):

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

【问题讨论】:

    标签: .net entity-framework lazy-loading


    【解决方案1】:

    您应该能够通过将 WeightGroups 设为虚拟来解决此问题,至少如果您使用的是 EF 4.1 或更高版本...

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

    您还必须在上下文中包含一个 DbSet...

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

    然后当你触摸属性时它会自动加载,例如显示在列表中。

    【讨论】:

    • 完美,谢谢。你能解释一下,为什么列表必须是虚拟的吗?顺便说一句,它也可以在没有额外的 DbSet&lt;&gt; 的情况下工作。
    • 在这种情况下,EF 所做的是创建 AgeGroup 类的子类并在 WeightGroups getter 中实现延迟加载。非常棒,因为您的代码始终可以假定 WeightGroups 可用,但如果您在某些情况下不触摸该属性,则它们不会被加载。
    猜你喜欢
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 2020-11-09
    相关资源
    最近更新 更多