索引数组超出范围异常
我尝试将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;
}
我失去了什么?
你似乎是创建和使用
bookingupdate = new BookingUpdate[c];
为数组分配内存,但实际上并不产生BookingUpdate实例。当您尝试在数组元素上设置属性时,没有实际的更新预订更新 - 只有一个持有者。
我建议沿着线改变你的代码的东西:
...
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"];
...
我希望这有助于!
bookingupdate = new BookingUpdate[c];
bookingupdate[c].bookingID = (long)rdr["ID"];
要创建长度c
的数组,这意味着它有指标0 to (c-1)
- 然后你是出界,试图在位置c
存储时。
您正在访问超出范围的n元素数组的第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
阵列具有从零开始的索引。
当您创建bookingupdate = new BookingUpdate[c];
时,您的最后一个索引将为c-1
。由于不是存在。
比方说c = 4
,这意味着我们定义一个数组,它包含4个元素;
BookingUpdate[0]
BookingUpdate[1]
BookingUpdate[2]
BookingUpdate[3]
BookingUpdate[c]
将等于BookingUpdate[4]
其中不存在这样的索引。
从MSDN
页面;
数组是零索引:与Ñ元素的数组是从0 索引到 n-1个。
该问题与数组大小有关;
for (int c = 0; c < count; c++)
{
bookingupdate = new BookingUpdate[c];
bookingupdate[c].bookingID = (long)rdr["ID"];
在前面的代码
,要创建在第一大小为0的数组(bookingupdate
);那么你正试图插入一个项目。即使你设法跳过第一个,它也会失败。只需将这些行更新为以下内容;
bookingupdate = new BookingUpdate[count];
for (int c = 0; c < count; c++)
{
bookingupdate[c].bookingID = (long)rdr["ID"];
for (int c = 0; c < count; c++)
{
bookingupdate = new BookingUpdate[c];
错误是在for循环,其中c是零的这种第一次迭代。即,您正尝试创建一个长度为零的数组。 bookingupdate = new BookingUpdate [0];
恕我直言,我将简化你的方式来构建阵列使用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();
在这条路上,你不会有界限以外的阵列问题。
在调用它之前,您已经初始化了一个数组,但不是该类本身。此外,您的初始化是错误的
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;
}
使用此代码
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;
}
我无法返回bookingupdate:名称bookingupdate doenst存在于当前上下文中 – 2013-02-13 09:21:24
editted now .. it should work .. – 2013-02-14 07:27:43
感谢您发现了另一个bug – 2013-02-13 10:54:41