为什么我可以使用Dapper而不是实体框架拥有多个数据读取器?

时间:2014-08-01 18:59:02

标签: database entity-framework dapper

我开始使用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()轻松解决这个问题,但是我有太多的记录只能一次将它们拉入内存。

所以这是一个由两部分组成的问题:

  1. 为什么停止工作?
  2. 我该如何解决?
  3. 我目前正在使用SQL Server,但我也想要一个支持其他数据库供应商的解决方案。

1 个答案:

答案 0 :(得分:1)

因为dapper假设大多数查询都是有限的结果,所以默认情况下缓冲区。它不是让读者保持打开状态,而是首先进行反序列化,然后将列表交给您。您需要指定一个参数(buffered),以便通过实时TDS流将其打开。虽然支持庞大的数据集非常重要,但它不是常态,所以dapper会优化小的结果作为默认值。

据推测,EF会做出另一种选择,默认情况下会给你一个开放的阅读器。补偿:致电ToList或类似:

foreach (var itemFromDb in getRecordsWithEf().ToList())