错误:while循环后读取器关闭时调用Read的尝试无效



你好,我有一个方法可以从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 + "nrStackTrace:nr" + ex.StackTrace);
    }
    finally
    {
        connection.Close();
    }
    return bookingupdate;
}

示例为:读取器关闭时调用Read的尝试无效

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;

(注意:为了可读性,我省略了try块)

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

DataTable.Load(IDataReader)加载数据后关闭读卡器。使用DataTable获取您加载的数据。

由于哪个读卡器位于EOF/Closed:,您已经在以下行处理了读卡器

dt.Load(rdr);

如果您想在上面的方法调用后处理记录,则应该使用您创建的DataTable对象dt,方法是在上面用dt.Rows.Count而不是while (rdr.Read())取消循环

从MSDN 中签出此主题

相关内容

  • 没有找到相关文章

最新更新