Cyn*_*hia 19 entity-framework lazy-loading eager-loading entity-framework-4
我发现我对延迟加载等感到困惑.
首先,这两个陈述是否相同:
(1) Lazy loading:
_flaggedDates = context.FlaggedDates.Include("scheduledSchools")
.Include ("interviews").Include("partialDayAvailableBlocks")
.Include("visit").Include("events");
(2) Eager loading:
_flaggedDates = context.FlaggedDates;
Run Code Online (Sandbox Code Playgroud)
换句话说,在(1)中,"包含"导致导航集合/属性与所请求的特定集合一起被加载,而不管您是否使用延迟加载......对吗?
在(2)中,语句将加载所有导航实体,即使您没有特别请求它们,因为您正在使用急切加载......对吗?
第二:即使您正在使用预先加载,在您"枚举可枚举"之前,数据实际上不会从数据库中下载,如下面的代码所示:
var dates = from d in _flaggedDates
where d.dateID = 2
select d;
foreach (FlaggedDate date in dates)
{
... etc.
}
Run Code Online (Sandbox Code Playgroud)
在foreach循环之前,数据实际上不会被下载("枚举")......对吗?换句话说,"var dates"行定义了查询,但直到foreach循环才执行查询.
鉴于(如果我的假设是正确的),渴望加载和延迟加载之间的真正区别是什么?似乎在任何一种情况下,数据在枚举之前都不会出现.我错过了什么吗?
(我的具体经验是代码优先,POCO开发,顺便说一句......虽然问题可能更普遍适用.)
Str*_*ior 17
您对(1)的描述是正确的,但它是Eager Loading而不是Lazy Loading的示例.
您对(2)的描述不正确.(2)在技术上根本不使用加载,但如果您尝试访问FlaggedDates上的任何非标量值,则将使用延迟加载.
在任何一种情况下,您都是正确的,在您尝试使用_flaggedDates"执行某些操作"之前,不会从数据存储中加载任何数据.但是,在每种情况下发生的情况都不同.
(1):预先加载:一旦你开始for
循环,已指定将得到从数据库中抽取,并建成一个巨大的内存中的数据结构中的对象的每一个.这将是一项非常昂贵的操作,从您的数据库中提取大量数据.但是,它将全部发生在一个数据库往返中,执行单个SQL查询.
(2):延迟加载:当你的for
循环开始时,它只会加载FlaggedDates对象.但是,如果访问for
循环内的相关对象,则它们不会将这些对象加载到内存中.检索给定FlaggedDate的scheduledSchools将导致在任何一个新的数据库往返的第一次尝试检索的学校,或者是因为你的背景已被释放引发异常.既然你可以访问内部的scheduledSchools收集for
循环,就必须为每一个您最初装在年初FlaggedDate一个新的数据库往返for
循环.
禁用延迟加载与启用Eager Loading不同.在这个例子中:
context.ContextOptions.LazyLoadingEnabled = false;
var schools = context.FlaggedDates.First().scheduledSchools;
Run Code Online (Sandbox Code Playgroud)
该schools
变量将包含一个空EntityCollection,因为我没有Include
在原来的查询它们(FlaggedDates.First()),我禁用延迟加载,使得已经执行的初始查询后,他们无法加载.
你是正确的,因为where d.dateID == 2
将意味着只有涉及到具体FlaggedDate对象的对象会在被拉动.但是,这取决于有多少个对象与该FlaggedDate,你仍然可以结束了一个大量的数据要超过该线的.这是由于EntityFramework构建其SQL查询的方式.SQL查询结果始终采用表格格式,这意味着每行必须具有相同的列数.对于每个scheduledSchool对象,结果集中至少需要有一行,并且因为每行必须包含至少一些每列的值,您最终会重复FlaggedDate对象上的每个标量值.因此,如果你有10个预定学校和10个与你的FlaggedDate相关的访谈,你最终会得到20行,每行包含FlaggedDate上的每个标量值.对于所有ScheduledSchool列,一半行将具有空值,而对于所有Interviews列,另一半将具有空值.
但是,如果你在你所包含的数据中"深入",那么这会变得非常糟糕.例如,如果每个ScheduledSchool有一个students
属性,你包括在内,然后突然你就必须为每个ScheduledSchool每个学生一排,并在每个那些行,为学生ScheduledSchool每标值将包括(即使只有第一行的值最终被使用),以及原始FlaggedDate对象上的每个标量值.它可以快速加起来.
这很难以书面形式解释,但是如果你看一下从多个Include
s 的查询中返回的实际数据,你会发现有很多重复的数据.您可以使用LinqPad查看EF代码生成的SQL查询.
归档时间: |
|
查看次数: |
15192 次 |
最近记录: |