【问题标题】:DataReader : Invalid attempt to read when no data is presentDataReader:不存在数据时尝试读取无效
【发布时间】:2012-07-18 20:14:22
【问题描述】:

我遇到了一些有趣的情况。我有以下代码来填充 DB (ASP.net) 中的字段值:

SqlConnection connect =
            new SqlConnection(
                @"conn-string"); 
SqlCommand toDo = new SqlCommand(InfoQuery, connect);
        toDo.CommandTimeout = 6000;
        connect.Open();
        using (SqlDataReader reader = toDo.ExecuteReader())
        {
            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    ///......retrieving some fields in the same way as below
                    foo = reader.SafeGetString(7);
                    int temp = reader.SafeGetInt32(8);
                    ///......retrieving again
                }
        }
        connect.close()

连接建立,所有参数都正确。在 SQL Server Management Studio 中,与 toDo 命令关联的查询非常完美。在程序中,当运行每个字段到 temp 值(不包括 temp)时,将被检索和设置。但是在读取温度值时,我得到以下异常:

不存在数据时尝试读取无效。

这是我的扩展方法:

public static class ExtentionMethods
{
    public static string SafeGetString(this SqlDataReader reader, int colIndex)
    {
        if (!reader.IsDBNull(colIndex))
            return reader.GetString(colIndex);
        return "NULL VALUE";
    }

    public static int SafeGetInt32(this SqlDataReader reader, int colIndex)
    {
        if (!reader.IsDBNull(colIndex))
            return reader.GetInt32(colIndex);
        return -1;
    }

    public static DateTime SafeGetDateTime(this SqlDataReader reader, int colIndex)
    {
        if (!reader.IsDBNull(colIndex))
        {
            try
            {
            }
            catch
            {
                return new DateTime(1800, 1, 1);
            }
        }
        return new DateTime(1800, 1, 1);
    }
}

查询:

SELECT TOP 1000 [ID0]
        ,[Id1]
        ,[Id2]
        ,Id1+Id2+'0' AS BC
        ,[Id3]
        ,[Id4]
        ,[Id5]
        ,CAST([Date] AS nvarchar(max))
        ,[int]
        ,[Id7]
        ,[Id8]
        ,IsNull(foo,'dsf')+' '+IsNull(bar,'dsf')+', '
        +IsNull(fgm,'fggf')+', fgfggf '+IsNull(gfgf,'gfgf')+
        ','+dfsdfsdsf+', '+dsffddf AS dsadsa
        ,[fg]
        ,[fds]
        FROM tbl
        inner join tbl1 on tbl1.ID=ID1
        inner join tbl2 on tbl2.ID=ID2
        WHERE Id4=12

问题可能是什么?

【问题讨论】:

  • 连接在哪里声明以及何时初始化?你也用using-statement吗?
  • 那些 7/8 应该是序数位置吗?我强烈建议您使用列名而不是序号位置。哎呀。
  • SafeGetString 有什么作用?它只是检查 DbNull 然后返回 string.empty 还是返回值?
  • 我没有使用连接对象的语句。然而,它被声明为高几行,并且是关闭的 using 语句。
  • 连接是静态的吗?你能展示更多这种方法吗?我不明白你最后评论的最后一句话。

标签: c# asp.net sql-server database


【解决方案1】:

我认为您不需要所有这些扩展方法,您应该按名称访问列:

while (reader.Read())
{
    int intCol = reader["MyIntColumn"] as int? ?? -1;
    string stringCol = reader["MyStringColumn"] as string ?? "NULL VALUE";
    DateTime dateCol = reader["MyDateColumn"] as DateTime? ?? new DateTime(1800, 1, 1);
}

int?DateTime? 将允许空值,如果该列为空,?? 将影响默认值。

【讨论】:

    猜你喜欢
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多