dapper - Reader.IsConsumed 为 false,但对象已被处置

标签 dapper idisposable sqldatareader objectdisposedexception

我正在使用QueryMultiple,它返回 GridReader .

由于我不知道要读取多少数据,因此我使用 IsConsumed 的停止条件循环读取器:

using (var reader = conn.QueryMultiple(mySql)) {
  while(!reader.IsConsumed) {
    reader.Read<...>
  }
}

但是,我在上次读取时总是收到 ObjectDisposeExceptionIsConsumed 的值仍然是 false

我尝试将 DynamicParameters 传递给查询,以获取回调(这似乎通过 IParameterCallbacks 很有用),但我无法修补一起。

我真的不想在代码中出现这样的预期异常。感谢您的帮助。

我使用的是 SQL Server,我的提供程序是 .NET 4.5 中的 System.Data.SqlClient,Dapper 版本 1.40.0.0

例如失败的测试:

        [TestMethod]
        public void QueryMultipleWithCursor()
        {

            const string sql = @"
DECLARE @CurrentDate DATE
DECLARE DatesCursor CURSOR LOCAL FOR
    SELECT DISTINCT DataDate FROM Data_Table ORDER BY DataDate 
OPEN DatesCursor
FETCH NEXT FROM DatesCursor INTO @CurrentDate

WHILE @@FETCH_STATUS = 0 BEGIN

    SELECT DISTINCT
        DataDate AS Date1,
        DataDate AS Date2
        FROM Data_Table
        WHERE DataDate=@CurrentDate

    FETCH NEXT FROM DatesCursor INTO @CurrentDate
END
CLOSE DatesCursor
DEALLOCATE DatesCursor";

            using (var conn = _database.GetConnection())
            {
                    var reader = conn.QueryMultiple(sql);
                    while (!reader.IsConsumed)
                    {
                            reader.Read<DateTime, DateTime, DateTime>(
                                (date1, date2) => date1,
                                splitOn: "Date2").ToList();
                    }
            }
        }

我收到带有以下堆栈的 NullReferenceException:

at Dapper.SqlMapper.GridReader.NextResult() in D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 4440
   at Dapper.SqlMapper.GridReader.<MultiReadInternal>d__9`8.System.IDisposable.Dispose()
   at Dapper.SqlMapper.GridReader.<MultiReadInternal>d__9`8.MoveNext() in D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 4309
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.GridReader.Read[TFirst,TSecond,TReturn](Func`3 func, String splitOn, Boolean buffered) in D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 4330
   at Project.MyTests.QueryMultipleWithCursor() in C:\Project\MyTests.cs:line 171
Result Message: 
Test method Project.MyTests.QueryMultipleWithCursor threw exception: 
System.NullReferenceException: Object reference not set to an instance of an object.

最佳答案

我推送了以下内容,它传递 SQL Server/SqlConnection;所以它可以工作:

[Fact]
public void SO35554284_QueryMultipleUntilConsumed()
{
    using (var reader = connection.QueryMultiple(
        "select 1 as Id; select 2 as Id; select 3 as Id;"))
    {
        List<HazNameId> items = new List<HazNameId>();
        while (!reader.IsConsumed)
        {
            items.AddRange(reader.Read<HazNameId>());
        }
        items.Count.IsEqualTo(3);
        items[0].Id.IsEqualTo(1);
        items[1].Id.IsEqualTo(2);
        items[2].Id.IsEqualTo(3);
    }
}

我想知道这里的问题是否是特定 ADO.NET 提供程序的问题。您可能需要准确指定:

  • 您正在使用什么后端 RDBMS/等(SQL Server?Oracle?Postgresql?...?)
  • 您正在使用什么 ADO.NET 提供程序
  • 您正在使用什么运行时(.NET 什么。什么? core-clr?)/操作系统
  • 您使用的具体库版本(以上是针对源代码的,与 1.50.0-beta8 最相似)

关于dapper - Reader.IsConsumed 为 false,但对象已被处置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35554284/

相关文章:

c# - 工厂应该跟踪创建的 IDisposable 对象吗?

c# - SQL数据读取器读取不一致

c# - 如何使用 dapper 返回包​​含其他类型列表的类型?

c# - 如何在 ADO.NET 对象上调用 Dispose?

c# - 使用 Dapper 和 Npgsql2 插入空值数组属性的问题

c# - 我的代码是否正确清理了它的 List<MemoryStream>?

c# - SQL 数据读取器返回错误日期

c# - 从 SqlDataReader 填充通用列表

c# - Dapper NullReferenceException

c# - 简单的 20 行选择查询(大多数列是 nvarchar(max))花费太长时间 - 15 秒或更长时间