实例化DbContext From EF是否读取整个数据库



在MVC3中实例化EntityFramework的DbContext时,是否读取整个数据库?调试时,可以通过查看实例化的DbContext来访问整个数据库中的所有数据,这难道不意味着在建立第一个连接时获取了所有数据吗?

不,绝对不是。当您访问DbContext的DbSet/ObjectSet属性时,将加载数据。

只有您查询的数据才会从数据库加载并映射到对象。例如,当你像一样查询时

DbContext.Table.Where(row => row.Prop1 == "Value")

它被转换为SQL,在数据库中进行评估,并且只有与您的查询匹配的行才会返回到您的应用程序。

否,实例化时不会读取整个数据库。DbContext中的实体集合(DbSet<>)是延迟求值的。因此,当您调试并导航到一个实例时,它会被查询,而不是在DbContext实例被实例化时。

否,实体框架只在您需要信息或需要修改信息时尝试查询数据库。

下面的例子是我对英孚在幕后所做的事情的个人解读。这可能有点不准确,但出于说明的目的。

using(var db = new MyDbContext()) // 1
{
    var entities = db.MyEntities; // 2
    foreach(var entity in entities) // 3
    {
        // 4
    } // 5
} // 6
  1. 建立与数据库的连接
  2. 获取一些表示查询的对象,该查询显示"获取所有dem实体"
  3. 枚举对象。Aka,让上下文的查询提供程序将"get me all dem entities"翻译为(假设sql)"select*from MyEntity with(nolock);",并运行返回ADO.NET SqlDataReader的查询,该查询将读取第一行,将对象映射到一个(可选)带有一些元数据的惰性对象,这样EF就知道它映射到了哪一行,等等,并将其作为"实体"变量
  4. 在不做任何实际工作的情况下,对您神奇地从数据库中收到的实体做一些事情(感谢实体框架!)
  5. 要求EF将SqlDataReader移到下一行并生成另一个实体(也就是说,返回步骤3,但前提是存在另一行)
  6. 关闭与数据库的连接

最新更新