我想知道LINQ和SqlDataProvider设法通过一个WHOLE表迭代。
对于以下示例,
整个foo项目是否已加载到ONCE和CLR的MEMORY中 迭代内存中的foo项?
或者foo项是从SQL Server中以块的形式加载的吗?
或者它们从SQL SERVER加载到MEMORT只有一个foo 一次?
或?
using (var context = new FooEntities())
{
var allItems = from foo in context.Foos
select foo;
// Are all foos LOADED into the MEMORY at once?
// Or they come from SQL SERVER in chunks?
foreach (f in foos)
Console.WriteLine(f.ID);
}
答案 0 :(得分:2)
这取决于ORM工具。目前还不清楚,但看起来像<{1}} 是实体框架吗?
首先,请注意,大多数“完整”ORM将(默认情况下)将其加载的所有对象附加到身份管理器/更改管理器中,这意味着一旦看到对象,它们就会在生命周期中保持不变ORM实例(尽管有时会禁用此方法)。
其次,请注意,FooEntities
之类的结果通常是“实体集”或类似的,一组完整的数据;但同样,它不是必然。
基本上,它取决于许多不在问题中的细节。但是,通常有API可以加载非缓冲(假脱机)数据,而无需附加到change-manager / identity-manager。例如,LINQ-to-SQL有.Foos
和其他一些切换。
如果您只是简单地使用一个懒惰的数据假脱机工具,将行具体化为对象,那么dapper可能会有用:
ObjectTrackingEnabled
答案 1 :(得分:0)
是的,一旦开始访问它。这些都被加载到内存中。
不会加载对象的virtual
属性。
如果您不想一次加载所有对象,可以使用Take
和Skip
进行分页。
// Take only 100 objects.
var someitems = allItems.Skip(100).Take(100);
要有更好的理解,请查看该文章。
答案 2 :(得分:0)
在您的具体示例中,您很可能将整个表格拉入内存。对数据库的调用将在foreach
开始时进行,并且看起来像SELECT * FROM FOO
。尝试踩过去看其他人建议的探查器。
SQL Server分析器非常适合这种东西,就像EFProfiler一样。请参阅此处:EFProfiler网站上的http://www.hibernatingrhinos.com/products/efprof/learn,了解使用Linq的一些“反模式”。这些实际上非常适用于任何类型的数据访问。还可以查看Joe Albahari的LINQ测验:http://www.albahari.com/nutshell/linqquiz.aspx以了解一些有趣的内容,以便注意LINQ。