提问人:Răzvan Puștea 提问时间:10/8/2023 最后编辑:NetråmRăzvan Puștea 更新时间:10/8/2023 访问量:59
IEnumerable vs List - 使用哪个(内存和性能)[重复]
IEnumerable vs List - which to use (memory & performance) [duplicate]
问:
我已经读了很多关于这个话题的文章,但我仍然感到困惑。 这是我所知道的(我写的内容与使用 LINQ 查询数据库有关):
- 每次我遍历集合或调用一些需要枚举的 LINQ 方法(Min、Max、ToList、FirstOrDefault 等)时,AsEnumerable() 都会执行查询 - “延迟加载”
- ToList() 将立即执行查询
- 如果我对集合执行许多操作,我应该使用 ToList() 来避免多次查询数据库。在以下情况下:
var test = _context.MyTable.Where(w => w.Conditions...).AsEnumerable(); // db returns 20 records
test.Where(w => w.Conditions); // from 20 records, I only have 10 now
是先将 20 条记录加载到内存中,然后再加载 10 条记录,还是从头开始加载 10 条记录?我试图了解何时应该使用 IEnumerable 而不是 List(它在幕后的工作方式)。
- 完成所有筛选后,我应该使用 IEnumerable 还是 List(或者没关系 - 性能相似)? 例:
var filteredRecords = _context.MyTable.AsNoTracking().Where(...).ToList();
var filteredRecords = _context.MyTable.AsNoTracking().Where(...).AsEnumerable();
我应该使用哪一个?FilteredRecords 将作为响应发送到客户端(例如 Angular)
答:
0赞
Netråm
10/8/2023
#1
- 在这种情况下,将从数据库中加载 20 条记录。您可以将其视为具体化数据库查询。如果计划执行进一步的 LINQ 操作,则几乎应始终将查询保留为 .某些 LINQ 操作无法与某些数据库提供程序一起执行,在这种情况下,您必须使用(或重写查询)。
AsEnumerable
IQueryable
AsEnumerable
- 这要视情况而定。正如你自己所想的那样,如果你打算多次迭代序列,你应该使用(或任何其他这样的替代方案)。如果您只打算迭代一次,那么使用 .某些数据库提供程序可以从数据库执行流式读取或缓冲读取,因此不需要将所有返回的记录保留在内存中。这可能只是预期返回大量记录的查询的问题。
ToList
ToArray
AsEnumerable
评论
0赞
Răzvan Puștea
10/8/2023
对于第二个示例,我不打算迭代它,我只是将集合返回给客户端。我注意到当我返回响应时执行了数据库查询(如 中所示)。为什么我应该使用 AsEnumerable() 而不是 ToList(),因为两者都将被执行(时间不相同)?return Ok(enumerableColection)
0赞
Răzvan Puștea
10/8/2023
我忘了谢谢你的回答。在阅读了几次之后,我明白了,当我计划只循环访问集合一次(或只是返回集合)时,我应该使用 IEnumerable。我感兴趣的是为什么会这样?我之所以问这个问题,是因为在第二个示例中,两个查询都将执行(时间不同)。为什么 IEnumerable 比 List 更有效?我将 EF Core 3 和 SQL Server 用于我的应用。
0赞
Netråm
10/8/2023
@RăzvanPuștea IEnumerable 并不比 List 更有效,但在某些情况下,它可能占用的内存更少。想象一下,一个查询将返回一百万条记录。使用 ,所有这些记录在写入客户端流之前都会被读入内存。使用 ,数据库提供程序可以批处理数据库读取,这意味着并非所有记录都同时在内存中。我不知道(Microsoft?SQL Server 的工作方式如下。ToList
AsEnumerable
0赞
Gert Arnold
10/9/2023
@Netråm没有数据库提供程序,只有数据库提供程序。只有执行的 LINQ 语句才有机会转换为 SQL。我之所以说机会,是因为只支持有限数量的 LINQ 操作。说这可以被认为是数据库查询的具体化是不正确的。事实并非如此。 确实如此。的主要影响是与数据库(或查询转换)提供程序的联系丢失。IEnumerable
IQueryable
IQueryable
AsEnumerable
ToList
AsEnumerable
评论
IQueryable<T>
IEnumerable<T>
ToList