【问题标题】:EF: how to eager load associations correctlyEF:如何正确加载关联
【发布时间】:2016-04-29 21:05:49
【问题描述】:

我在我的应用程序中使用 EF 进行数据访问。数据模型(大大简化):

class Project 
{
  virtual ICollection<Foo> Foos {get;set;}
  virtual ICollection<Bar> Bars {get;set;}
  // actually I have many more kinds of Project's data
}

class Foo 
{
  virtual Project Project {get;set;}
  virtual ICollection<Bar> LinkedBars {get;set;}
  //And they are greatly intervened with each other
}
//etc etc.

要点是:

  • 所有FooBar等都相互引用
  • 这个引用永远不会离开Project,即以下总是正确的: foo.Bars.All(bar =&gt; bar.Project == foo.Project) == true

我加载项目如下:

var project = Db.Set<Project>
              .Include(p => p.Foos)
              .Include(p => p.Bars);

所以,在那之后,如果我访问一些foo.Bars,我会触发延迟加载。这是意料之中的,毕竟我已经急切地从ProjectFooBar 加载了所有需要的数据,但没有从Foo_Bar 链接表加载。

让我们修改一下:

var project = Db.Set<Project>
              .Include(p => p.Foos.Select(f => f.Bars))
              .Include(p => p.Bars);

现在我在内存中有所有需要的数据,但是(!)生成的 SQL 显然不是最佳的。实际上,EF 正在加载 ProjectFooFoo_Bar 表并扫描 Bar 两次——一次用于 p.Bars,一次用于 foo.Bars。所以,我不能急切加载foo.Bar_Ids 而不急切加载foo.Bars,可以吗?

我应该如何改进?

【问题讨论】:

  • 我们正在俄罗斯圣彼得堡招聘 C# 开发人员 :-)

标签: entity-framework


【解决方案1】:

AFAIK 获得此功能的唯一方法是将 Foo_Bars 声明为显式链接表(不是由 EF6 自动生成的),并且 Include

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多