gpt4 book ai didi

c# - 如何使用 Linq to Entities 处理大型结果集?

转载 作者:太空狗 更新时间:2023-10-29 21:30:56 24 4
gpt4 key购买 nike

我在网站上显示了一个相当复杂的实体查询 linq。它使用分页,所以我一次不会拉下超过 50 条记录进行显示。

但我还想为用户提供将完整结果导出到 Excel 或其他文件格式的选项。

我担心的是,为了执行此操作,可能会同时将大量记录全部加载到内存中。

有没有一种方法可以像使用数据读取器那样一次处理 1 条记录的 linq 结果集,因此一次真正只将 1 条记录保存在内存中?

我看到过一些建议,如果您使用 foreach 循环枚举 linq 查询,那么记录将不会立即全部读入内存,并且不会使服务器不堪重负。

有没有人有指向我可以阅读的内容的链接以验证这一点?

如果有任何帮助,我将不胜感激。

谢谢

最佳答案

set the ObjectContext to MergeOption.NoTracking (因为它是一个只读操作)。如果您使用相同的 ObjectContext 来保存其他数据,Detach the object从上下文。

如何分离

foreach( IQueryable)
{
//do something
objectContext.Detach(object);
}

编辑:如果您使用的是NoTracking选项,则无需分离

Edit2:我写信给Matt Warren关于这个场景。并在他的同意下在这里发布相关的私有(private)信件

The results from SQL server may noteven be all produced by the serveryet. The query has started on theserver and the first batch of resultsare transferred to the client, but nomore are produced (or they are cachedon the server) until the clientrequests to continue reading them.This is what is called ‘firehosecursor’ mode, or sometimes referred toas streaming. The server is sendingthem as fast as it can, and the clientis reading them as fast as it can(your code), but there is a datatransfer protocol underneath thatrequires acknowledgement from theclient to continue sending more data.

由于 IQueryable 继承自 IEnumerable,我相信发送到服务器的底层查询是相同的。但是,当我们执行 IEnumerable.ToList() 时,底层连接使用的数据读取器将开始填充对象,对象将加载到应用程序域中,并且可能会耗尽内存中这些对象还不能被释放。

当您使用 foreachIEunmerable 时,数据读取器会一次读取一个 SQL 结果集,然后创建对象,然后将其释放。基础连接可能会以 block 的形式接收数据,并且在读取所有 block 之前可能不会将响应发送回 SQL Server。因此,您不会遇到“内存不足”异常

编辑3:

当您的查询正在运行时,您实际上可以打开 SQL Server“事件监视器”并查看查询,任务状态为已暂停,等待类型为 Async_network_IO - 这实际上表明结果是在 SQL Server 网络缓冲区中。您可以阅读更多相关信息 herehere

关于c# - 如何使用 Linq to Entities 处理大型结果集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3055778/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com