1

SQL 結果を配列に保存して戻そうとします。しかし、私は例外を取得しています: 配列が範囲外エラーです。

ここに私のコードがあります:

 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;
        rdr = cmd.ExecuteReader();


            while (rdr.Read())
            {
                DataTable dt = new DataTable();
                dt.Load(rdr);
                count = dt.Rows.Count;
                for (int c = 0; c < count; c++)
                {
                    bookingupdate = new BookingUpdate[c];
                    bookingupdate[c].bookingID = (long)rdr["ID"]; // <---- Error is here
                    bookingupdate[c].fullUserName = rdr["VERANSTALTER"].ToString();
                    bookingupdate[c].newStart = (DateTime)rdr["VON"];
                    bookingupdate[c].newStart = (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;
                    }

                }

            }

    }

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

私は何が欠けていますか?

4

9 に答える 9

2
bookingupdate = new BookingUpdate[c];
bookingupdate[c].bookingID = (long)rdr["ID"]; 

length の Array を作成していますc。つまり、 Indexes があることを意味します。Position0 to (c-1)に格納しようとすると、範囲外になりますc

于 2013-02-13T09:02:42.310 に答える
1

私は、Linqでその配列を構築する方法を簡素化します:

BookingUpdate[] bookingupdate = dt.AsEnumerable()
    .Select(r => new BookingUpdate{
        bookingID = r.Field<long>("ID"),
        fullUserName = r.Field<string>("VERANSTALTER"),
        newStart = r.Field<DateTime>("Von"),
        newEnd = r.Field<DateTime>("Bis"), // here was another bug in your originalcode
        newSubject = r.Field<string>("THEMA"),
        newlocation = r.Field<string>("BEZEICHNUNG"),
        deleted = r.Field<string>("STORNO") != null
    })
    .ToArray();

この方法では、範囲外の配列で問題が発生することはありません。

于 2013-02-13T09:07:07.423 に答える
1

配列のメモリを作成して割り当てているようです

bookingupdate = new BookingUpdate[c];

ただし、実際に BookingUpdate のインスタンスを作成するわけではありません。配列要素にプロパティを設定しようとすると、更新する実際の BookingUpdate はありません。ホルダーは 1 つだけです。

コードを次のようなものに変更することをお勧めします。

...
bookingupdate = new BookingUpdate[count];  // allocates space for the number of BookingUpdates to be created
for (int c = 0; c < count; c++)
{
    bookingupdate[c] = new BookingUpdate(); // create a new instance of BookingUpdate and assign it the array     
    bookingupdate[c].bookingID = (long)rdr["ID"];
    ...

これが役立つことを願っています!

于 2013-02-13T09:14:29.260 に答える
0

範囲外の n-Elements 配列の n 番目の要素にアクセスするには、n - 1 要素にアクセスする必要があります。

bookingupdate = new BookingUpdate[c];   // You create an array of 5 elements for example 
bookingupdate[c].bookingID = (long)rdr["ID"]; // Here you access the 5th elements but there are only 4
于 2013-02-13T09:03:21.030 に答える
0

配列にはゼロから始まるインデックスがあります。

bookingupdate = new BookingUpdate[c];最後のインデックスを作成すると、 c-1.

存在しBookingUpdate[c]ないためアクセスできません。

たとえばc = 4、4 つの要素を持つ配列を定義したことを意味します。

BookingUpdate[0]
BookingUpdate[1]
BookingUpdate[2]
BookingUpdate[3]

BookingUpdate[c]BookingUpdate[4]は、そのようなインデックスが存在しないものと等しくなります。

ページからMSDN;

配列のインデックスは 0 です。n 個の要素を持つ配列は、 0から n-1までのインデックスが付けられます。

于 2013-02-13T09:04:33.253 に答える
0

問題は配列のサイズに関連しています。

 for (int c = 0; c < count; c++)
 {
    bookingupdate = new BookingUpdate[c];
    bookingupdate[c].bookingID = (long)rdr["ID"];

bookingupdate前のコードでは、最初にサイズ 0の配列 ( ) を作成しています。次に、アイテムを挿入しようとしています。なんとか最初の 1 つをスキップできたとしても、再び失敗します。これらの行を次のように更新するだけです。

bookingupdate = new BookingUpdate[count];
for (int c = 0; c < count; c++)
     {        
        bookingupdate[c].bookingID = (long)rdr["ID"];
于 2013-02-13T09:05:43.947 に答える
0
            for (int c = 0; c < count; c++)
            {
                bookingupdate = new BookingUpdate[c];

エラーは、c がゼロのこの for ループの最初の繰り返しです。つまり、長さゼロの配列を作成しようとしています。bookingupdate = 新しい BookingUpdate[0];

于 2013-02-13T09:06:10.410 に答える
0

このコードを使用

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";
BookingUpdate[] bookingupdate;
SqlConnection connection = new SqlConnection(GetConnectionString());

connection.Open();
try
{
    SqlCommand cmd = new SqlCommand(command, connection);
    SqlDataReader rdr = null;
    int count = 0;
    rdr = cmd.ExecuteReader();


        while (rdr.Read())
        {
            DataTable dt = new DataTable();
            dt.Load(rdr);
            count = dt.Rows.Count;
            bookingupdate = new BookingUpdate[count];
            for (int c = 0; c < count; c++)
            {
                bookingupdate[c].bookingID = (long)rdr["ID"]; // <---- Error is here
                bookingupdate[c].fullUserName = rdr["VERANSTALTER"].ToString();
                bookingupdate[c].newStart = (DateTime)rdr["VON"];
                bookingupdate[c].newStart = (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;
                }

            }

        }

}

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

}

于 2013-02-13T09:10:34.400 に答える
0

配列を初期化しましたが、呼び出す前にクラス自体を初期化していません。また、初期化が間違っています

count = dt.Rows.Count;
bookingupdate = new BookingUpdate[count];
for (int c = 0; c < count; c++)
{
    bu = new BookingUpdate();
    bu.bookingID = (long)rdr["ID"]; // <---- Error is here
    bu.fullUserName = rdr["VERANSTALTER"].ToString();
    bu.newStart = (DateTime)rdr["VON"];
    bu.newStart = (DateTime)rdr["BIS"];
    bu.newSubject = rdr["THEMA"].ToString();
    bu.newlocation = rdr["BEZEICHNUNG"].ToString();
    if (rdr["STORNO"].ToString() != null)
    {
        bu.deleted = true;
    }
    else
    {
        bu.deleted = false;
    }
    bookingupdate[c] = bu;
}
于 2013-02-13T09:07:07.790 に答える