2013-02-14 2 views
-1

Здравствуйте, у меня есть метод, который считывает некоторые данные из sql и сохраняет их в массивы.Ошибка: Неправильная попытка вызова Чтение, когда считыватель закрыт после цикла while?

, чтобы узнать, сколько строк в результате 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; 
} 

Exeption является: Invalid попытки вызвать чтение, когда читатель закрыт

+0

В какой строке находится ошибка? – DGibbs

+2

Тот же вопрос с http://stackoverflow.com/questions/14849780/indexing-array-out-of-range-exception ?? –

+0

его другой вопрос с тем же методом –

ответ

3

Load -Method закрывает DataReader, поэтому следующий вызов Read() завершается с ошибкой (хорошо, это то, что говорит об исключении).

После того, как вы читаете эти данные в свой DataTable, можно просто запросить и использовать проекцию Select чтобы создать BookingUpdate экземпляров (нет необходимости для while -loop/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, чтобы сделать ваш код более читабельный.

+0

благодарю вас за информацию. оно работает –

0

Вы уже обработали читатель на следующую строку, благодаря которой читатель находится на EOF/Closed:

dt.Load(rdr); 

Если вы хотите обработать записи после вызова метода выше, вы должны использовать ваш созданный DataTable объект dt по строке выше unsing цикл с dt.Rows.Countвместо из while (rdr.Read())

Checkout эту тему от MSDN

1

DataTable.Load(IDataReader) закрывает считыватель после загрузки данных из него. Используйте DataTable, чтобы получить данные, которые вы загрузили.

Смежные вопросы