.SqlDataReader.ReadColumnHeader的NullReferenceExcep

2019-10-18 13:48发布

这个问题在一定程度上关系到我以前的一个答案,这帮助我找到为什么这个简单的迭代直通SqlDataReader的原因:

m_aFullIDList = New Generic.List(Of Integer)

While i_oDataReader.Read
    m_aFullIDList.Add(i_oDataReader.GetInt32(0))
End While

m_iTotalNumberOfRecords = m_aFullIDList.Count

不返回的所有记录。 原来当Generic.List改变其容量以容纳更多的元素(例如,从2 ^ 19到下一个2 ^ 20)在这一点上SqlDataReader的简单对等的,因为如果没有更多的记录其Read方法返回False。

它的大部分悄然退出的时间,没有异常被抛出任何。 但每一个现在,然后我得到:

的NullReferenceException {“对象引用不设置为一个对象的一个​​实例。”}

在System.Data.SqlClient.SqlDataReader.ReadColumnHeader(的Int32ⅰ)
在System.Data.SqlClient.SqlDataReader.ReadColumn(的Int32 I,布尔的setTimeout)在System.Data.SqlClient.SqlDataReader.GetInt32(的Int32ⅰ)

我知道一个事实,即由阅读器(这是一个单柱)使用存储过程返回的所有记录是整数值。 如果我删除线m_aFullIDList.Add ,而是简单的读值转换成整数变量,如果我预先分配泛型列表能力的认识一大批-这个问题是不会发生。 显然,它只有在名单重新分配容量发生 - 这会影响读者。

我也试图尽快使用其他结构(ArrayList中,甚至阵列,使用Array.Resize)作为这种结构的能力被重新分配超过某一点 - 这打破了SqlDataReader对象。

这ASP.NET项目是有点复杂,所以当我试图重现该问题在仅由执行阅读器和阅读列表变成一个独立的简单的项目 - 这个问题是不会发生。 任何想法是怎么回事,如何这可以解决吗?

Answer 1:

我想,我终于想通了。

在我的代码逻辑有两个步骤 - 调用返回SqlDataReader的功能,然后使用该读者在另一个函数来填充列表:

Dim oReader as SqlDataReader = GetTheReader()

FillTheList(oReader)

功能GetTheReader()看起来是这样的:

Function GetTheReader() as SqlDataReader
   Dim oConn As New SqlConnection("Connection String") : oConn.Open()
   Dim oComm As New SqlCommand("Stored Procedure", oConn)

   Dim oReader As SqlDataReader = oComm.ExecuteReader(CommandBehavior.CloseConnection)

   Return oReader
End Function

它打开连接,其中又以超出范围时,该函数返回给调用者的局部变量。 而被填充泛型列表中时,陆续容量分配垃圾收集摧毁过时的变量(和关闭该连接)声称,内存。 我留下了一个SqlDataReader没有一个有效的连接。

我的当前的解决方案是创建外部连接GetTheReader功能,并将其传递作为参数之一。



文章来源: .SqlDataReader.ReadColumnHeader NullReferenceException