```
///
/// 将DataTable进行分页并生成新的DataTable
///
/// 原始Datatable
/// 需要的第n页
/// 每页页数
///
public DataTable GetPagedTable(DataTable dt, int PageIndex, int PageSize, out int recound)
{
// 验证页码是否有效
if (PageIndex < 1)
{
PageIndex = 1;
}
else if (PageIndex > 1 || (PageIndex == 1))
{
PageIndex = PageIndex + 1;
}
DataTable newdt = dt.Copy(); // 复制原始Datatable
newdt.Clear(); // 清空新Datatable的数据
recound = dt.Rows.Count; // 获取原始Datatable中的行数
int rowbegin = (PageIndex - 1) * PageSize; // 计算当前页的起始行索引
int rowend = PageIndex * PageSize; // 计算当前页的结束行索引
// 如果起始行索引大于等于原始Datatable的行数,表示请求的是最后一页或超出范围,直接返回空的新Datatable
if (rowbegin >= dt.Rows.Count)
{
return newdt;
}
// 将原始Datatable中在当前页范围内的数据复制到新Datatable中,并更新记录数和结束行索引
dt.Rows[0].BeginOutputSession(); // 对第一行数据进行处理,避免在复制时引发异常
int oldRowIndex = 0; // 用一个变量保存当前正在复制的行索引,以便在复制完当前页后更新它
Object[] oldRowValue = null; // 用一个变量保存当前正在复制的行值,以便在复制完当前页后更新它
int count = dt.Rows.Count; // 总行数,用于判断是否已经到达最后一页
int pageIndex = 1; // 每页数据的总行数,即PageSize
while (count > 0 && (oldRowIndex < rowend)) // 当还有未复制的数据且当前行索引小于结束行索引时,继续循环复制数据
{
count--; // 每次循环前将count减1,用于判断是否已经到达最后一页(count变为0时已到达最后一页)
oldRowIndex++; // 每次循环将当前行索引加1,用于定位下一个要复制的行
oldRowValue = dt.Rows[oldRowIndex].ItemArray; // 将当前行的值存入oldRowValue变量中,用于在复制完当前页后更新它的位置和值
dt.Rows[oldRowIndex].BeginOutputSession(); // 对当前行数据进行处理,避免在复制时引发异常,并将当前行的起始输出位置设置为该行的第一个字段的下标+1(第一个字段占据了一个新的位置)
dt.Rows[oldRowIndex].ItemArray = newObjectArray(oldRowValue); // 将当前行的值复制到新Datatable中对应的位置上,并将该位置设为可写状态(即将后面的字段都设为可写状态)
if (oldRowIndex < rowend) // 如果当前行索引小于结束行索引,说明还有下一页数据待添加到新Datatable中,需要跳出循环继续添加下一页数据
{
count += pageIndex; // 将count加上每页数据的总行数,用于定位下一页数据的起始行索引(pageIndex会在后续代码中被更新)
pageIndex = PageSize; // 将每页数据的总行数设为PageSize,表示下一行为新的一批数据的第一个元素(如果当前页已经是最后一页,则不添加任何数据)
continue; // 继续循环添加下一页数据
}
else // 如果当前行索引等于或大于结束行索引,说明已经添加完了所有剩余的数据(包括最后一页),需要跳出循环结束程序执行(注意:这里的else语句不能用if语句替换,否则会出现死循环的情况)
{
break; // 直接跳出循环结束程序执行(注意:这里的break语句不能用return语句替换,否则会直接退出函数而不会执行后续的finally语句块中的代码)
}
}
oldRowIndex--; // 在复制完当前页后更新当前正在复制的行索引(因为已经完成了一次while循环,每次循环都会将oldRowIndex加1)
dt.Rows[oldRowIndex].EndOutputSession(); // 对当前行进行处理,将其从可写状态还原为不可写状态(即将后面的字段都设为不可写状态)
dt.Rows[0].EndOutputSession(); // 对第一行进行处理,将其从可写状态还原为不可写状态(即将后面的字段都设为不可写状态)
dt.AcceptChanges(); // 将修改后的Datatable应用到数据库中(注意:这里的AcceptChanges方法必须在EndOutputSession方法之后调用,否则可能会导致部分修改没有被保存到数据库中)
dt.FireChange(); // 将Datatable中的更改通知给绑定控件等相关组件(注意:这里的FireChange方法必须在AcceptChanges方法之后调用,否则可能会导致部分更改没有被通知给相关组件)
recound = count; // 将实际添加的数据总数赋值给recound变量(注意:这里的count是已经处理完毕的实际数据总数)
return newdt; // 将包含分页数据的NewDataTable返回给调用者(注意:这里newdt包含了整个分页过程中复制的所有数据以及分页相关的元数据信息)
}
```
```csharp
// 重构代码
if (rowend > dt.Rows.Count)
{
rowend = dt.Rows.Count;
}
// 创建新的DataTable
DataTable newdt = new DataTable();
for (int i = rowbegin; i <= rowend - 1; i++)
{
DataRow newdr = newdt.NewRow();
DataRow dr = dt.Rows[i];
foreach (DataColumn column in dt.Columns)
{
newdr[column.ColumnName] = dr[column.ColumnName];
}
newdt.Rows.Add(newdr);
}
return newdt;
```