问题:我要从数据库中处理数百万行。
我需要实现一个返回数据库行的"流"(?)的方法。 我不想立刻将所有内容加载到内存中。
我正在考虑返回一个懒惰的IEnumerable<Record>
并使用yield。
该方法将使用SqlDataReader
处理连续记录。
但是当客户在.Count()
上拨打IEnumerable
时会发生什么?计算所有记录意味着需要全部获取它们。
有没有什么好的现代方法可以返回一个没有将所有对象存储在内存中的对象流,只需逐个处理?我的方法应该返回一个记录流。
似乎Reactive Extensions可能会为我解决问题,但我从未使用它。
有什么想法吗?
由于
答案 0 :(得分:2)
首先,为什么重新发明轮子?实体框架使得更容易做到这样的事情并为您添加所有抽象。 DbSet<TEntity>对象上的DbContext实现了IQueryable<TEntity>和IEnumerable<T>,因此您可以:
如果你坚持使用ADO.NET并手动执行此操作(我理解遗留代码并不总是可以选择使用EF),那么从连接中打开数据读取器是最好的方法。这将在每个下一个记录中读取每个对应的方法Read()的调用,这是在DB中读取记录的最便宜的方法。
如果你想要一个Count,那么我建议你写一个新的sql查询,它返回一个使用Sql在数据库服务器上执行的计数
SELECT COUNT(field) FROM table
因为这是最佳做法。不要迭代并总结读者的所有记录,并通过一些自定义的工作来执行内存中的总和,这将浪费资源,更不用说创建复杂的代码而没有任何好处。
答案 1 :(得分:0)
对于count查询db,并返回给用户。
另一方面,您只需要为ICollection实现count,IEnumerable不需要。只需返回IEnumerable以便对记录进行迭代。
请注意,您正确处理了与db的连接。