2012-01-26 82 views
0

让我们假设我有三个表: 类别,项目和CategoriesToItems实体框架生成不必要的查询

类别和项目之间的关系是许多一对多(通过CategoriesToItems表)。

让我们假设我调用一些方法,我们执行以下代码方法内(强制执行查询的数据/枚举立即):

var categories = context.Categories.ToList(); 
var items = context.Items.ToList(); 
var links = context.CategoriesToItems.ToList(); 

在此之后,我立即开始检查每个产品像这样:

foreach(Category category in categories) 
{ 
    foreach(Item item in links.Select(l => l.Item)) 
    { 
     //Do some stuff. 
    } 
} 

为什么这些foreach循环生成对数据库的查询? EF不应该已经知道所有必需的信息,因为我加载了类别,项目和链接表条目?

有趣的是,如果我改变了一点东西,并加载想通过类似的循环,使

var items = context.Items.ToList(); 
var categories = context.Categories.Include("CategoriesToItems").ToList(); 

运行不生成查询时,我想知道的产品在任何特定类别的数据是什么。

我关心的原因是加载数据的第一种方式要快得多,但之后我必须立即对数据执行操作,并且性能会慢得多(因为每次都会生成额外的查询) 。

实际的include子句比较复杂,因为我们需要来自多个不同表的数据,这就是为什么单独加载整个表比加载精细生成的多重连接查询加载整个表更快的原因(我们需要所有的它们中的数据)。在真正的应用程序中有更多的表格(类别可以有标签,项目可以有标签,两种关系都是多对多的 - 我确信你得到的图片 - “做东西”部分实际上是建立一个字典中的项目/类别以及它们所具有的标签和标签都是继承的,因此标有X的类别表示其所有产品都标有X)。当我从所有相关表中加载的每一个单列 为什么在实体框架生成有关的关系查询:


要概括/这简化了一点点?我能做些什么来帮助这种情况?


编辑:我要补充一点,我假设它的实际拨打电话到数据库,因为在LiveTrace显示了ADO.NET查询条目时,这些代码特定行执行并因为性能明显不同。所以,如果我误解了那些LiveTrace条目的含义,那么我想我会遇到一个不同的问题。

回答

0

尝试之前关闭延迟加载到执行任何查询:

context.ContextOptions.LazyLoadingEnabled = false;