【问题标题】:OracleDataReader throws exceptionOracleDataReader 抛出异常
【发布时间】:2011-01-07 19:53:43
【问题描述】:

在我当前的应用程序中,我需要执行 SQL 查询,并在继续之前获取返回结果的计数。这是我下面的代码:

if (GetCount(reader) == 1)
                {
                    reader.Read();
                    Console.WriteLine(reader["field1"]);
                    Console.WriteLine(reader["field2"]);
                }

这就是GetCount() 方法

public static int GetCount(OracleDataReader reader)
        {
            int count = 0;

            while (reader.Read())
            {
                count++;
            }

            return count;
        }

收到结果计数后,进入if代码块,抛出异常:

[System.InvalidOperationException] = {"Operation is not valid due to the current state of the object."}

但是,如果我没有得到计数,它可以正常工作。

我认为由于我的 GetCount 函数具有 reader.Read(),我需要在读取值之前以某种方式重置读取器吗?老实说,我很难过。有什么建议吗?

编辑; 在第一个代码块中,即使我注释掉 reader.Read();,我也会得到相同的异常

【问题讨论】:

    标签: c# sql oracle


    【解决方案1】:

    GetCount() 之后,您已经遍历了您的阅读器。在调用下一个 reader.Read() 之前,您需要对您的价值观做一些事情,否则您将失去它们。基本上你正在尝试iterate through your reader twice,这是你做不到的。

    您可以通过引用将DataSet 传递给GetCount() 并填充它,然后在主代码块中引用DataSet。但是,如果您确实将其放入 DataSet,则您实际上不需要自己计算任何内容,因为 DataSet 具有足够的属性。

    例子:

    myDataset.Tables[0].Rows.Count
    

    编辑: 试试这个

    OracleDataAdapter adapter = new OracleDataAdapter(yourSQLQuery,yourConnString);
    DataSet data = new DataSet();
    
    adapter.Fill(data);
    
    if (data.Tables.Count != 0)
    {
        if (data.Tables[0].Rows.Count == 1)
        {
            ...
        }
    }
    

    【讨论】:

    • 但是当我通过值将 reader 传递给 GetCount 时,它不会复制,所以我原来的 reader 保持不变?
    • @xbonez 阅读器是引用类型意味着您发送的是引用的副本,而不是阅读器的副本。因此,您指向的是同一个读者
    • 这可能是一个糟糕的解决方法,但是在将 reader 传递给 GetCount 之后,如果我将其复制到另一个 Datareader 变量并使用它来获取计数,它会起作用吗?
    • 试过这样做。我仍然遇到同样的错误。我会尝试使用数据集方法。
    • 您的解决方法仍然不起作用,因为 DataReader 类型实际上并不包含数据,它只是为您提供了一种从查询填充的缓冲区中获取数据的方法,否则您不会不需要对每条记录执行 read(),您只需引用它在数据集中的位置。
    【解决方案2】:

    由于您使用的是阅读器,因此您已到达终点,需要重新设置才能回到起点。

    看起来你并不真正关心计数是多少,只是它有行。所以你可以只使用 HasRows 属性。

    if (reader.HasRows)
    {
        reader.Read();
        Console.WriteLine(reader["field1"]);
        Console.WriteLine(reader["field2"]);
    }
    

    如果您确实需要行数,这将不起作用,但在此示例中,这无关紧要。

    http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracledatareader.aspx

    【讨论】:

    • 这将获得列数,而不是行数。
    猜你喜欢
    • 2014-02-23
    • 2019-08-04
    • 2013-05-24
    • 2011-05-30
    • 1970-01-01
    • 2011-02-25
    • 2012-01-24
    相关资源
    最近更新 更多