njammy
1. В вашем коде сохраняйте переменные startIndex, pageSize и totalRows.
2. На инициализации, установите значение параметра startindex = 0.
3. Установите pageSize по умолчанию, например pageSize = 10 или все, что вы хотите/пользователь хочет.
4. Установите currentPage на 1.
5. Установите totalRows для записи количества записей из результата запроса.
6. Возьмите количество исходных строк и скопируйте их в целевую таблицу
См. пример кода (извините за многословие, но я использовал веб-сайт dotNetFiddle, чтобы попробовать его для вас).
7. все, что вам нужно сделать, это указать текущую страницу, и она получит строки для этого диапазона.
Примечание:это будет не очень хорошая производительность на больших наборах. Используйте LINQ или переместите логику подкачки, показанную здесь, на сторону базы данных, используя параметры и временную таблицу, чтобы получить столбцы идентификатора ссылки.
using System;
using System.Data;
using System.Collections.Generic;
using System.Xml;
public class Program
{
private static DataTable dt;
private static DataTable refDt;
private static int startIndex;
private static int pageSize = 5;
private static int currentPage = 3;
private static int totalRows;
private static int totalPages;
public static void Main()
{
// Simulating a query result data bind.
dt = new DataTable("MyDataTable");
dt.Columns.AddRange(new DataColumn[]
{
new DataColumn("col1"),
new DataColumn("col2"),
new DataColumn("col3")
});
List<object[]> data = new List<object[]>
{
new object[] { "1.1", "1.2", "1.3" },
new object[] { "2.1", "2.2", "2.3" },
new object[] { "3.1", "3.2", "3.3" },
new object[] { "4.1", "4.2", "4.3" },
new object[] { "5.1", "5.2", "5.3" },
new object[] { "6.1", "6.2", "6.3" },
new object[] { "7.1", "7.2", "7.3" },
new object[] { "8.1", "8.2", "8.3" },
new object[] { "9.1", "9.2", "9.3" },
new object[] { "10.1", "10.2", "10.3" },
new object[] { "11.1", "11.2", "11.3" },
new object[] { "12.1", "12.2", "12.3" },
};
foreach(object[] dataItems in data)
{
dt.Rows.Add(dataItems);
}
// Now do the paging:
totalRows = dt.Rows.Count;
// Set up a reference table to track ids as the source DT may be sorted etc and spoil the tracker field.
refDt = new DataTable("RefDt");
refDt.Columns.AddRange(new DataColumn[]
{
new DataColumn("Index"),
new DataColumn("Id")
});
for(int i=0;i<dt.Rows.Count;i++)
{
// Here, the refDt data table is built up to store a reference to each ID field in source datatable
// along with a row number
refDt.Rows.Add(new object[] {Convert.ToString(i), dt.Rows[i]["col1"]});
//Console.WriteLine("Index:" + refDt.Rows[i].ItemArray[0] + ", Id:" + refDt.Rows[i].ItemArray[1]);
}
// Now lets work out how many to take and copy to destination data table
DataTable dest = new DataTable("Destination");
dest = dt.Clone(); // <- copys columns/schema but not data.
startIndex = (currentPage * pageSize) - pageSize;
Console.WriteLine("Reading " + pageSize + " rows starting at row index " + startIndex);
for(int i = startIndex; (pageSize * currentPage) > totalRows ? i < totalRows : i < pageSize * currentPage; i++)
{
string lookupFilter = "Index = '" + i.ToString() + "'";
DataRow dr = (DataRow)refDt.Select(lookupFilter)[0];
string id = Convert.ToString(dr[1]);
string selectFilter = "col1 = '" + id + "'";
DataRow source = dt.Select(selectFilter)[0];
dest.Rows.Add(source.ItemArray);
// Just to prove it only copies the required range
string output= "";
for(int c = 0; c < dest.Columns.Count; c++)
{
output += Convert.ToString(dest.Rows[dest.Rows.Count-1][c]) + ", ";
}
Console.WriteLine(output.Remove(output.Length-2,2));
}
int remainderRows = dt.Rows.Count % pageSize;
totalPages = remainderRows > 0 ? totalRows/pageSize + 1: totalRows/pageSize;
Console.WriteLine("Last page has " + remainderRows + " rows");
Console.WriteLine("Page " + currentPage + " of " + totalPages + " (Total " + dt.Rows.Count + " rows)");
}
}