ORM(Linq-SQL EF)是不是从表中加载整个数据集?
Posted
技术标签:
【中文标题】ORM(Linq-SQL EF)是不是从表中加载整个数据集?【英文标题】:Does ORM (Linq-SQL EF) load entire data set from table?ORM(Linq-SQL EF)是否从表中加载整个数据集? 【发布时间】:2011-04-15 23:09:00 【问题描述】:有关 ORM(Linq to SQL,EF 4)如何处理数据加载的问题。是否加载了整个数据集,如果是,我们可以阻止加载整个数据集并加载一个子集吗?例如,在实例化上下文和查询时,如果返回所有数据(数十万条记录)与实例化连接、为给定数据子集执行 proc 并查询该数据子集,似乎会出现巨大的性能问题。我没有看到很多线程解决了这个问题,提前谢谢!
【问题讨论】:
【参考方案1】:不,它不会,因为 Linq to Sql/Eft 将解析查询以生成优化的 sql 查询来检索您的数据,据说滥用扩展方法(调用 GetEnumrator()
)或查询可能最终从表中加载所有项目。
滥用调用GetEnumerator()
的扩展方法
context.Books.ToList().Where(somePredicate).Select(someSelector);
这将导致整个Books
表被加载,因为ToList()
将调用sql 查询来检索所有Book
对象。从那里你 Where
和 Select
实际上是在 Linq to objects 而不是 Linq To Sql/Entities 上操作。
context.Books.Where(somePredicate).Select(someSelector).ToList();
只需将.ToList()
推到语句末尾,EF 就会将查询解析为有效的 sql 查询,并在调用.ToList()
时检索您的部分图书。
滥用Func<T, bool>
考虑以下,
Func<Book, bool> predicate = b=>b.Id == 3;
context.Where(predicate).ToList();
现在这看起来完全有效,但是一旦您运行查询,您会发现上下文正在加载所有Books
,这是什么?简而言之,EF 无法将 Func<T, bool>
谓词解析为有效的 sql 语法,因为 Func<>
只是一个委托。这个简单的错误可能导致 EF 将所有 Books 加载到上下文中,然后针对加载的 Books 运行 Linq to Objects。
Expression<Func<Book, bool>> predicate = b=>b.Id == 3;
context.Where(predicate).ToList();
现在我们将使用Expression<Func<Book, bool>>
,它只是一个表达式树,EF 知道如何解析表达式树,并且能够创建一个有效的 sql 语句,该语句只加载一个 Book
,ID 为 3 .
我相信其他人能够加入更多可能导致加载整个表格的示例,但是这些是您最有可能遇到的。
【讨论】:
正是我想要的。谢谢【参考方案2】:如果我理解您的问题,Linq 2 Sql 不会加载数据集中的所有内容。创建上下文并构建 linq 2 sql 语句后,只有语句中引用的表才会被拉回,除非您明确告诉 dataContext 使用 DataLoadOptions 加载相关表。
现在,如果您在谈论分页,请使用 Skip and Take。
其他人可以加入 EF,因为我没有太多经验,但我无法想象它会有太大的不同。不过我喜欢 Linq 2 sql,它对我来说已经足够快了。
【讨论】:
以上是关于ORM(Linq-SQL EF)是不是从表中加载整个数据集?的主要内容,如果未能解决你的问题,请参考以下文章