```

///

/// 将DataTable进行分页并生成新的DataTable

///

/// 原始Datatable

/// 需要的第n页

/// 每页页数

/// 新的DataTable

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;

```