当在MVC3中实例化EntityFramework的DbContext时,整个数据库是否被读取?调试时,通过查看实例化的DbContext可以访问整个数据库中的所有数据,这是否意味着在第一次连接时所有数据都被抓取?是否从EF实例化DbContext读取整个数据库?
1
A
回答
3
不确定不是。当您访问DbContext的DbSet/ObjectSet属性时,将加载数据。
只有您查询的数据从数据库中加载并映射到对象。例如,当你查询像
DbContext.Table.Where(row => row.Prop1 == "Value")
其转换为SQL,在数据库,只有符合您查询的行计算返回到您的应用程序。
2
不,整个数据库不会在实例化中读取。惰性评估您DbContext中的实体集合(DbSet <>)。因此,当您调试并导航到一个时,它将被查询,而不是在DbContext实例被实例化时。
1
不,实体框架试图只在需要信息时查询数据库,或者您需要修改信息。
下面的例子是我个人对我认为EF在幕后做了什么的解释。这可能有些不准确,但仅供说明之用。
using(var db = new MyDbContext()) // 1
{
var entities = db.MyEntities; // 2
foreach(var entity in entities) // 3
{
// 4
} // 5
} // 6
- 建立与数据库
- 连接获取一些对象,表示查询,说:“给我所有的数字高程模型的实体。”
- 枚举该对象。也就是说,让上下文的查询提供程序将“让我所有的数据实例”翻译成(假定为sql)“select * from MyEntity with(nolock);”,然后运行查询返回一个ADO.NET SqlDataReader,它将读取第一行,将对象映射到一个带有一些元数据的(可选的)惰性对象中,这样EF就知道它映射到哪一行了,并且将它作为“实体”变量。
- 跟你从数据库中神奇地收到没有真正做任何实际工作(感谢实体框架!)
- 问EF到SqlDataReader对象移动到下一行,并产生另一个实体的实体的东西(也就是,回到步骤3,但前提是存在另一行)
- 关闭与数据库的连接。