我开始使用Dapper开发应用程序,但我认为对于某些查询,使用Entity Framework会很不错。所以我正在重构我的一些查询。在仅有Dapper的日子里,我有一些类似的代码:
foreach (var itemFromDb in getRecordsWithDapper())
{
var toInsert = doSomeComputations(itemFromDb);
insertRecordWithDapper(toInsert);
}
这非常有用,因为无论我的数据库中有多少数据,我都不必担心内存。我一次只处理一条记录。
所以现在我已经重构,以便我的查询完全相同,但使用Entity Framework 6:
foreach (var itemFromDb in getRecordsWithEf())
{
var toInsert = doSomeComputations(itemFromDb);
insertRecordWithDapper(toInsert);
}
但是现在我在InvalidOperationException
中收到insertRecordWithDapper()
,并显示消息“已经有一个与此命令关联的打开的DataReader必须先关闭。”我可以通过使用getRecordsWithEf().ToArray()
轻松解决这个问题,但是我有太多的记录只能一次将它们拉入内存。
所以这是一个由两部分组成的问题:
我目前正在使用SQL Server,但我也想要一个支持其他数据库供应商的解决方案。
答案 0 :(得分:1)
因为dapper假设大多数查询都是有限的结果,所以默认情况下缓冲区。它不是让读者保持打开状态,而是首先进行反序列化,然后将列表交给您。您需要指定一个参数(buffered
),以便通过实时TDS流将其打开。虽然支持庞大的数据集非常重要,但它不是常态,所以dapper会优化小的结果作为默认值。
据推测,EF会做出另一种选择,默认情况下会给你一个开放的阅读器。补偿:致电ToList
或类似:
foreach (var itemFromDb in getRecordsWithEf().ToList())