我们假设我有三张桌子: 类别,项目和类别项目
类别和项目之间的关系是多对多的(通过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 :(得分:0)
尝试在执行任何查询之前关闭延迟加载:
context.ContextOptions.LazyLoadingEnabled = false;