IQueryable 加载数据的方式(一次性加载到内存/分批加载)


前言

在 .NET 中,IQueryable 是一种支持 延迟执行 的接口,常用于 LINQ 查询。它允许将查询逻辑转换为底层数据源(如数据库)的原生查询语言(如 SQL),从而优化性能。


一、一次性从数据库加载数据到内存和分批从数据库读取

对比ADO.Net 中读取数据的方式

  1. DataReader:分批从数据库服务器读取数据。内存占用小、DB连接占用时间长;
  2. DataTable:把所有数据一次性从数据库服务器都加载到客户端内存中。内存占用大,节省DB连接

验证IQueryable用什么方式

  1. 给表T_Articles插入适量数据(通过以下SQL)。

    INSERT into [dbo].[T_Articles](Title,Content)
    SELECT Title,Content FROM [dbo].[T_Articles]
    
  2. 然后遍历IQueryable(加上Delay/Sleep,延长遍历内容的时间),在遍历执行过程中,停止SQLServer服务器。

    foreach (var item in dbContext.Articles)
    {
        Console.WriteLine(item.Title);
        Thread.Sleep(10);
    }
    
  3. 会发现程序运行异常。
    异常提示数据库服务不可用,说明IQueryable是一直连接着数据库,它是类似DataReader的方式一批一批的从数据库读取数据。

    异常信息:A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
    
  4. 优点: 节省客户端内存。

  5. 缺点:长时间占用数据库连接。

如何一次性加载所有数据到内存

用IQueryable的ToArray()、ToArrayAsync()、ToList()、ToListAsync()等方法。

var res=dbContext.Articles.ToList();

二、何时需要一次性加载所需数据

  1. 遍历IQueryable并且进行数据处理的过程比较耗时。
  2. 如果方法需要返回查询结果,并且在方法里销毁DbContext的话,是不能返回IQueryable的,必须一次性加载返回。
  3. 多个IQueryable的遍历嵌套。很多数据库的ADO.Net Core
    Provider是不支持多个DataReader同时执行的。SQL Server
    数据库通过配置数据库连接字符串中的MultipleActiveSets=true属性可以支持

总结

IQueryable 的核心优势是 将查询逻辑推送到数据源执行,而非在内存中处理。合理使用可以显著提升性能,尤其是在处理数据库时。需要结合具体场景选择加载方式,并注意避免常见陷阱。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值