【发布时间】:2016-02-22 12:54:37
【问题描述】:
我正在使用QueryMultiple,它返回一个GridReader。
由于我不知道我要读取多少数据,所以我以IsConsumed 的停止条件循环阅读器:
using (var reader = conn.QueryMultiple(mySql)) {
while(!reader.IsConsumed) {
reader.Read<...>
}
}
但是,我在最后一次阅读时总是收到ObjectDisposedException。 IsConsumed 的值仍然是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.
【问题讨论】:
-
重新编辑:我使用 .NET 4.5、Dapper 1.40.0、
SqlClient设置了一个测试平台,一切正常。 pastie.org/10733819 - 我很乐意尝试并提供帮助 - 如果有错误:修复它。但我无法重现该问题。你能帮我举一个不符合你描述方式的例子吗? -
你能在相同的配置和测试上尝试像 Marc 这样的独立测试吗?我想知道在多个上下文中使用相同的连接对象,比如并行任务,你可以在其中获得相同 GridReader 的引用,其中一个读取和关闭,因此消耗和其他抛出对象处理异常
-
我添加了一个失败的单元测试。我无法通过足够简单的测试重现
ObjectDisposedException,但我已经非常接近了。我知道测试仍然很复杂,但我不明白为什么它不应该工作。
标签: dapper idisposable sqldatareader objectdisposedexception