指定的强制转换在使用数据读取器时无效。

3

大家好,我是stackoverflow的朋友。

我在这里写问题,因为我有时无法检测到数据读取器中字段的读取返回一个无效的转换异常。我将提供尽可能多的信息来理解我的情况。我正在使用ASP.NET 3.5。

  • I have a Module that have a function that returns a IDataReader and receives a sql query. something like this

    function get_dr(query as String) as IDataReader
    dim connection = new SqlClient.SqlConnection("connection string")
    connection.open()
    dim command = connection.createCommand
    command.commandText = query
    dim reader = command.executeReader(CommandBehavior.CloseConnection)
    return reader
    end function
    
  • I have a Class with a Shared function that recovers a new dataReader and returns a date. something like this:

    public shared function getDate() as Date    
    using dr = get_dr("SELECT dbo.getDate()")    
    if dr.read() and dr(0) isnot dbnull.value then   
    return dr.GetDateTime(0)   
    end if   
    end using   
    end function   
    
当我在另一个代码中调用getDate()函数时,它会给我一个类似于这样的调用堆栈。
System.InvalidCastException: Specified cast is not valid.
at System.Data.SqlClient.SqlBuffer.get_DateTime()
at System.Data.SqlClient.SqlDataReader.GetDateTime(Int32 i)

有时候我会遇到这个错误,我认为这是因为很多用户与我的应用程序中的其他函数(这些函数最终也会使用 get_dr)一起调用此函数,将数据的数据读取器混合在另一个执行中,但我需要知道是否我做错了什么或者有更好的方法。
注意事项: - dbo.getDate 是一个始终返回日期的 SQL 函数。 - 不要担心糟糕的代码编写,这只是示例,但它们具有理解场景所必需的内容。 - 对于我的糟糕的英语,我感到抱歉。
非常感谢您的帮助。
1个回答

0

可能的一个原因是 - 你在返回 DataReader 的函数内部声明了连接。当你退出该函数时,该连接就超出了作用域。这意味着在某个不可预测的时间点(取决于内存使用等)垃圾回收器将对其进行回收。如果在那个时候尝试使用 DataReader,则一切都无法保证。

解决方法之一是在 function get_dr 外部声明连接并将其作为参数传递给该函数。但是,如果您不打算使用读取器获取多个值,并且只返回单个值,则建议使用 ExecuteScalar - 这将节省您很多麻烦。


感谢Yuriy的帮助,这里的学校不教这样的东西:( 你的答案对我来说非常清晰,但你是否知道一些更详细解释这种情况的文档吗? 可悲的是,在我正在工作的项目中,它经常使用get_dr函数来读取多个值。 - Fernando Andrs Sepulveda Silva
@FernandoAndrsSepulvedaSilva 很遗憾,有些东西学校无法给予,它们必须来自经验。我曾经遇到过非常类似的问题,花了很多时间去找解决方法,最终找到了原因。我写了一篇小博客,以便如果有人遇到相同的问题,他们可以找到解决方案:http://codecorner.galanter.net/2013/08/30/solution-for-sqldatareader-readcolumnheader-nullreferenceexception/ 但总的来说,在.NET方面,请查阅“变量作用域”和“垃圾回收”。 - Yuriy Galanter
我很高兴我的解决方案有用。如果有其他问题,请创建一个新的Stack Overflow问题,这样你可以得到更多的帮助。 - Yuriy Galanter
再次感谢Yuriy,我会像你提到的那样阅读一些关于变量作用域的信息。有一次我也看到了一些奇怪的东西,就是当我们的应用程序使用get_dr函数读取“nvarchar”字段时,它最终通过dataReader.Item属性返回了一个“date”值(即使在该字段中不存在任何日期值!)。我认为使用返回dataReader的函数并不是一个真正好的主意...我会将您的答案标记为已接受,因为它对我帮助很大。 - Fernando Andrs Sepulveda Silva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接