使用Include()时,如何避免在EF中生成大量SQL查询

时间:2013-03-21 05:02:10

标签: entity-framework entity-framework-4

我正在使用EF(dll版本为4.4)来查询数据库。该数据库包含几个包含课程信息的表。当看看实际发送给db的内容时,我看到了一个巨大的,近1300行的SQL查询(由于它的大小,我不会在这里粘贴)。我在上下文中运行的查询如下所示:

entities.Plans
  .Include("program")
  .Include("program.offers")
  .Include("program.fees")
  .Include("program.intakes")
  .Include("program.requirements")
  .Include("program.codes")
  .Include("focuses")
  .Include("codes")
  .Include("exceptions")
  .Include("requirements")
where plans.Code == planCode
select plans).SingleOrDefault(); 

我想避免在从每个相关表中收集信息时回到服务器,但是如果有这么大的查询,我想知道是否有更好的方法可以做到这一点?

感谢。

5 个答案:

答案 0 :(得分:1)

有点晚了,但是,由于您的数据每天只更改一次,请查看将所需内容放入索引视图并将此视图放在EF模型中。

答案 1 :(得分:0)

您通常可以在where子句后添加.Include()。这意味着您只是提取符合您想要的信息,看看是否会减少您的查询。

答案 2 :(得分:0)

当您正在执行急切加载时,如果您选择所需的实体,则其罚款。否则你可以使用延迟加载,但是如你所指定的那样你不想要数据库往返,所以你可以避免它。

我建议,如果多次使用此查询,则可以使用编译查询。这样可以提高性能。

如果你想要,请浏览此链接..    http://msdn.microsoft.com/en-us/library/bb896297.aspx

答案 3 :(得分:0)

如果您正在使用DbContext,则可以使用上下文中的.Local属性来查看您的实体是否已被检索并因此附加到上下文。

如果查询之前已经运行并且您的根Plan实体已经基于Plan.Code == planId附加了,那么可能它的子实体也已经附加了,因为您已经开始加载,所以通过它来引用它们导航属性在该上下文的生命周期内不会再次为它们命中数据库。

article可能有助于您使用.Local

答案 4 :(得分:0)

Include

如果在上下文中禁用延迟加载,则此类查询将导致实体的导航属性使用查询中包含的实体进行填充。

(我只在EF.dll v5.0上对此进行了测试,但它在EF.dll v4.4上应该表现相同,这只是.NET 4.0上的EF5。当我使用这种模式测试而不是{ {1}}在类似形状的查询中,它从500行SQL中删除约70行。您的里程可能会有所不同。)