c# - DbContext:延迟加载不必要的数据库调用?
问题描述
我有一个非常基本的示例 C# 程序,它使用 EF6 和 DbContext 并包含两个类:
MyTable1 1...n MyTable2
我有以下代码:
// Creation of instances and saving them to the database.
using (var context = new EFTestEntities()) {
var myTable1 = new MyTable1() { ID = 1 };
var myTable2 = new MyTable2() { ID = 2 };
myTable1.MyTable2.Add(myTable2);
context.MyTable1.Add(myTable1);
context.SaveChanges();
}
// Getting the above objects in another context.
// This part here is what my question is about.
using (var context = new EFTestEntities()) {
var myTable1 = context.MyTable1.Where(e => e.ID == 1).FirstOrDefault();
var myTable2 = context.MyTable2.Where(e => e.ID == 2).FirstOrDefault();
var myTable2AssignedToMyTable1 = myTable1.MyTable2.FirstOrDefault();
}
我的问题是关于上面代码的第二部分。
启用延迟加载后,我会收到三个数据库调用。每行一个。变量myTable2AssignedToMyTable1
包含 then myTable2
- 这是正确的。
禁用延迟加载后,我会收到两个数据库调用。一个用于第一行,一个用于第二行。该变量myTable2AssignedToMyTable1
也包含myTable2
- 没有第三个数据库调用。这对我来说很有意义,因为myTable2
在第 2 行加载。
但是:如果不需要第三个数据库调用,为什么在启用延迟加载时进行?
当我在 SQL Server Profiler 中检查有无延迟加载的数据库调用时,我意识到它们完全相同(除了第三次调用)。第三次调用的数据与第一次或第二次调用的数据相同。因此,当第三次调用发生时,所需的数据已经在上下文中。当延迟加载被禁用时,EF 会实现它并使用已经加载的数据。当启用延迟加载时,它不会意识到它并再次从数据库中获取相同的数据。为什么?
它比MyTable2
在上下文中找到正确的实例更快吗?
还是比总是先在上下文中搜索正确的实例然后进行数据库调用更快?可以假设在大多数情况下所需的数据尚未在上下文中。所以我猜 EF 设计者决定不先检查上下文。在大多数情况下,无论如何都会错过。
但这些只是我的假设。知道真正的原因会很有趣。
解决方案
推荐阅读
- javascript - 如何在 SVG 图像上创建弹出气球?
- verilog - systemVerilog 中的逐位否定
- asp.net - MVC如何在动作参数中传递两个输入文本
- python - Python3:在不中断导入的情况下将包含子类/超类的自包含 git 子模块导入更大的项目结构
- r - 试图抓取到 csv 文件
- php - 如何在php中关闭模态后删除消息
- c++ - 向量
损坏的 C++ - firebase - Firebase 和世博会。部署 Expo 应用程序。隐藏键
- javascript - 带有嵌入式迷你图的 Highcharts 工具提示
- c - 通过 STM32 闪存获得 CRC-32 并与其他 CRC-32 工具保持一致