ff 核心托雷模拟

EF Core ToArray analog

你们中的大多数人都知道 ToList()、ToArray() 使用大量内存,因为它们会在 N 个元素之后重新创建数组。我需要从 table 中获取所有行,我这样写的

ToArray(_dbContext.MyTable.Count(), _dbContext.MyTable.Select(x => ...})

T[] ToArray<T>(int arraySize, IEnumerable<T> list)
    {
      var result = new T[arraySize];
      byte tempIndex = 0;
      foreach (var item in list)
      {
        result[tempIndex] = item;
        tempIndex++;
      }
      return result;
    }

此代码使用的内存比简单代码少约 10%

_dbContext.MyTable.Select(x => ...}).ToList() \ ToArray()

EF 有没有和我的代码类似的东西?

您使用的内存较少,但可以肯定的是,如果 table 很大 and/or 您的数据库不是本地的,此操作将花费更多时间 运行。

您正在数据库中执行两个查询,例如:

  1. select count(*) from MyTable
    
  2. select * from MyTable
    

EF 使用单个查询来实现相同的功能。我认为 10% 的内存对于更好的性能来说是一个非常小的代价。因此,EF 没有此行为。

EF 没有这个,但建议的方法也不是一个好的解决方案。

建议的解决方案不好,因为它在数据库上运行两个查询,而且额外的数据库调用往往会超过额外的 RAM 使用。但是假设您知道结果的大小(可能是因为分页)并且可以跳过额外的数据库查询。 即便如此,仍然比需要

相反,优化它的方法是首先认识到在大多数情况下 ToArray()ToList() 都不是必需的。学习直接使用生成的 IEnumerableIQueryableIAsyncEnumerable 等。您已经可以将它们用于数据绑定或在 foreach 循环中创建您需要的任何结果;根本不需要调用 ToArray()

大多数时候你 似乎 需要 ToList()ToArray(),这是因为你正在调用一个方法,要求它的参数类型。这些方法也应该更新为请求 IEnumerableIAsyncEnumerable。如果你能把它一直推到链下,你的代码的内存效率可以显着提高,因为完整的结果集是从不载入内存;您一次只能在内存中保存一条记录。