LINQ是否只将SQL Server中的所有项加载到内存或块中?

时间:2012-10-22 12:48:24

标签: c# .net sql-server linq sqldatareader

我想知道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);
}

3 个答案:

答案 0 :(得分:2)

这取决于ORM工具。目前还不清楚,但看起来像<{1}} 是实体框架吗?

首先,请注意,大多数“完整”ORM将(默认情况下)将其加载的所有对象附加到身份管理器/更改管理器中,这意味着一旦看到对象,它们就会在生命周期中保持不变ORM实例(尽管有时会禁用此方法)。

其次,请注意,FooEntities之类的结果通常是“实体集”或类似的,一组完整的数据;但同样,它不是必然

基本上,它取决于许多不在问题中的细节。但是,通常有API可以加载非缓冲(假脱机)数据,而无需附加到change-manager / identity-manager。例如,LINQ-to-SQL有.Foos和其他一些切换。

如果您只是简单地使用一个懒惰的数据假脱机工具,将行具体化为对象,那么dapper可能会有用:

ObjectTrackingEnabled

答案 1 :(得分:0)

是的,一旦开始访问它。这些都被加载到内存中。

不会加载对象的virtual属性。

如果您不想一次加载所有对象,可以使用TakeSkip进行分页。

// Take only 100 objects.
var someitems = allItems.Skip(100).Take(100);

要有更好的理解,请查看该文章。

  

Linq to SQL Deferred Loading - Lazy Load

答案 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。