EF6渴望在POCO内部加载

时间:2016-11-08 19:56:51

标签: c# entity-framework

让我们说,我有这样的结构:

  • 分支:Id
  • 组:Id
  • BranchGroup:BranchId,GroupId,Since,Till

关系为Branch 1..N BranchGroup 1..1 Group,因此生成的Branch类具有ICollection<BranchGroup> BranchGroups导航属性。

Branch POCO中有一个属性,返回当前组(简化了一点):

public List<Group> Groups => BranchGroups.Where(bg => bg.Since <= DateHelper.Current && 
                                                      bg.Till >= DateHelper.Current)
                                          .Select(bg => bg.Group).ToList();

我打电话给它,数据库爆炸了数以千计的查询,每个查询都是一组。是否有可能以某种方式优化它而无法访问dbContext(或至少从实体内部到达当前上下文)?

UPD:最简单的真实查询如下所示:

public List<Group> Groups => BranchGroups.Where(bg => bg.Since <= DateHelper.Current && 
                                                      bg.Till >= DateHelper.Current)
                                          .Select(bg => bg.Group)
                                          .Where(g => !g.Deleted).ToList();

1 个答案:

答案 0 :(得分:1)

这似乎是不可能的 - 无论何时访问导航属性(在这种情况下为BranchGroups),都会从数据库中提取整个相关集,因此查询的其余部分(Where,Select,Where)将在数据集在内存中,因此它不会转换为数据库查询。然后,bg.Group也是导航属性,因此要获得一个,就会执行单独的数据库查询,就像您观察到的那样。

真正的POCO对象不应该与DbContext有任何关系,它们只是普通的对象。因此,您不能(也不应该)从POCO内部(或者不再是POCO)到达上下文。

所以你的选择是:

  1. 构建分支对象时填充组属性(如果您不总是需要加载这些组,则不好)。
  2. 借助外部上下文引用(而非POCO内部)获取组。
  3. 也许,在构造Branch对象时,像这样设置Groups属性:

      branch.Groups = context.BranchGroups.Where(c => c.BranchID = branch.ID && ...); // the rest of your query
    

    然后它仍然是POCO(组只是IEnumerable)但包含你需要的查询,它在访问时是延迟加载的(并且没有对上下文的显式引用)。