错误:在while循环后关闭阅读器时无效尝试调用Read?

时间:2013-02-14 11:19:21

标签: c# sql sqldatareader

您好我有一个方法从sql中读取一些数据并将它们保存到数组中。

找出sql结果我写了多少行:

DataTable dt = new DataTable();
            dt.Load(rdr);
            count = dt.Rows.Count;

之后,sqldatareader将结果保存到数组中。

这是我的完整代码:

 public BookingUpdate[] getBookingUpdates(string token)
{
    String command = "SELECT b.ID,b.VERANSTALTER, rr.VON ,rr.BIS, b.THEMA, b.STORNO, ra.BEZEICHNUNG from BUCHUNG b JOIN RESERVIERUNGRAUM rr on rr.BUCHUNG_ID = b.ID JOIN RAUM ra on ra.ID = rr.RAUM_ID WHERE b.UPDATE_DATE BETWEEN DATEADD (DAY , -20 , getdate()) AND getdate() AND b.BOOKVERNR = 0";
    SqlConnection connection = new SqlConnection(GetConnectionString());
    BookingUpdate[] bookingupdate = new BookingUpdate[1];
    connection.Open();
    try
    {
        SqlCommand cmd = new SqlCommand(command, connection);
        SqlDataReader rdr = null;
        int count = 0;
        int c = 0;

        rdr = cmd.ExecuteReader();
        DataTable dt = new DataTable();
        dt.Load(rdr);
        count = dt.Rows.Count;
        bookingupdate = new BookingUpdate[count];

        while (rdr.Read())   // <--- HERE COMES THE ERROR
        {
                bookingupdate[c] = new BookingUpdate();
                bookingupdate[c].bookingID = Convert.ToInt32(rdr["ID"]);
                bookingupdate[c].fullUserName = rdr["VERANSTALTER"].ToString();
                bookingupdate[c].newStart = (DateTime)rdr["VON"];
                bookingupdate[c].newEnd = (DateTime)rdr["BIS"];
                bookingupdate[c].newSubject = rdr["THEMA"].ToString();
                bookingupdate[c].newlocation = rdr["BEZEICHNUNG"].ToString();
                if (rdr["STORNO"].ToString() != null)
                {
                    bookingupdate[c].deleted = true;
                }
                else
                {
                    bookingupdate[c].deleted = false;
                }
                c++;

        }
    }

    catch (Exception ex)
    {
        log.Error(ex.Message + "\n\rStackTrace:\n\r" + ex.StackTrace);
    }
    finally
    {
        connection.Close();
    }
    return bookingupdate;
}

该例外是:读取器关闭时调用Read的无效尝试

3 个答案:

答案 0 :(得分:3)

Load - 方法会关闭DataReader,因此对Read()的跟随调用失败(嗯,这是异常告诉您的内容)。

将数据读入DataTable后,您只需查询并使用Select投影即可创建BookingUpdate个实例(无需while - 环路/ BookingUpdate[])。所以你的代码基本上可以减少到

String command = "SELECT b.ID,b.VERANSTALTER, rr.VON ,rr.BIS, b.THEMA, b.STORNO, ra.BEZEICHNUNG from BUCHUNG b JOIN RESERVIERUNGRAUM rr on rr.BUCHUNG_ID = b.ID JOIN RAUM ra on ra.ID = rr.RAUM_ID WHERE b.UPDATE_DATE BETWEEN DATEADD (DAY , -20 , getdate()) AND getdate() AND b.BOOKVERNR = 0";
SqlCommand cmd = new SqlCommand(command, new SqlConnection(GetConnectionString()));
connection.Open();

DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());

var bookingupdate = dt.Rows.OfType<DataRow>().Select (row => 
                    new BookingUpdate
                    {
                        bookingID = Convert.ToInt32(row["ID"]),
                        fullUserName = row["VERANSTALTER"].ToString(),
                        newStart = (DateTime)row["VON"],
                        newEnd = (DateTime)row["BIS"],
                        newSubject = row["THEMA"].ToString(),
                        newlocation = row["BEZEICHNUNG"].ToString(),
                        deleted = row["STORNO"].ToString() != null // note that this line makes no sense. If you can call `ToString` on an object, it is not 'null'
                    }).ToArray();

return bookingupdate;

(注意:为了便于阅读,我省略了试用块)

您可能还想查看DataRowExtensions,尤其是Field方法,以使您的代码更具可读性。

答案 1 :(得分:1)

DataTable.Load(IDataReader)在从中加载数据后关闭读者。使用DataTable获取您加载的数据。

答案 2 :(得分:0)

由于哪个读者位于EOF/Closed

,您已经在以下行处理了读者
dt.Load(rdr);

如果您想在上述方法调用之后处理记录,应该使用您创建的DataTable对象dt通过上面的行unsing for {{1而{em>代替 dt.Rows.Count

MSDN

查看此主题