Как разбить или разделить DataTable на C#?
Я хочу разделить DataTable, чтобы я мог загружать его куски из одного места в другое.
выбрать первые 100 строк.
выбрать следующие 100 строк.
выбрать следующие 100 строк и так далее ...
есть ли способ сделать это так же, как курсор в базе данных? Я не люблю использовать петли и т. д. для подсчета рядов.
6 ответов
YourDataTable.Select()
дает вам массив
как насчет linq?
к примеру YourDataTable.Select (x => x).Take (100).ToEnumerable()
дает вам первые 100 DataRows
и YourDataTable.Select (x => x).Skip(100).Take (100).ToEnumerable()
для следующих 100.
попробуйте это:
public static class DataExtensions
{
public static IEnumerable<IEnumerable<DataRow>> Partition(this DataTable dataTable, int partitionSize)
{
var numRows = Math.Ceiling((double)dataTable.Rows.Count);
for(var i = 0; i < numRows / partitionSize; i++)
{
yield return Partition(dataTable, i * partitionSize, i * partitionSize + partitionSize);
}
}
private static IEnumerable<DataRow> Partition(DataTable dataTable, int index, int endIndex)
{
for(var i = index; i < endIndex && i < dataTable.Rows.Count; i++)
{
yield return dataTable.Rows[i];
}
}
}
var partitions = dataTable.Partition(100);
делаем:
dataTable.Skip(0).Take(100);
dataTable.Skip(100).Take(100);
dataTable.Skip(200).Take(100);
dataTable.Skip(300).Take(100);
будет повторяться 0 раз и принимать 100 при первом выполнении. Затем повторите 100 строк, возьмите 100, затем повторите 200 строк,затем возьмите 100 и т. д.
вышеуказанное сделает ленивую выборку и только ударит каждую строку один раз
Это просто способ сделать это:
public DataSet test(DataSet ds, int max)
{
int i = 0;
int j = 1;
DataSet newDs = new DataSet();
DataTable newDt = ds.Tables[0].Clone();
newDt.TableName = "Table_" + j;
newDt.Clear();
foreach (DataRow row in ds.Tables[0].Rows)
{
DataRow newRow = newDt.NewRow();
newRow.ItemArray = row.ItemArray;
newDt.Rows.Add(newRow);
i++;
if (i == max)
{
newDs.Tables.Add(newDt);
j++;
newDt = ds.Tables[0].Clone();
newDt.TableName = "Table_" + j;
newDt.Clear();
i = 0;
}
}
return newDs;
}
можно попробовать?
использовать linq выбрать часть записи эта ссылка в Stack overflow может быть полезна разделить коллекцию на n частей с помощью LINQ?
проверка: разделение большого datatable на меньшие пакеты из c-sharpcorner.com
internal static List<datatable> SplitTable(DataTable originalTable, int batchSize)
{
List<datatable> tables = new List<datatable>();
DataTable new_table = new DataTable();
new_table = originalTable.Clone();
int j = 0;
int k = 0;
if (originalTable.Rows.Count <= batchSize)
{
new_table.TableName = "Table_" + k;
new_table = originalTable.Copy();
tables.Add(new_table.Copy());
}
else
{
for (int i = 0; i < originalTable.Rows.Count; i++)
{
new_table.NewRow();
new_table.ImportRow(originalTable.Rows[i]);
if ((i + 1) == originalTable.Rows.Count)
{
new_table.TableName = "Table_" + k;
tables.Add(new_table.Copy());
new_table.Rows.Clear();
k++;
}
else if (++j == batchSize)
{
new_table.TableName = "Table_" + k;
tables.Add(new_table.Copy());
new_table.Rows.Clear();
k++;
j = 0;
}
}
}
return tables;
}
Improving on @vanessa
public DataSet SplitDataTable(DataTable tableData, int max)
{
int i = 0;
int j = 1;
int countOfRows = tableData.Rows.Count;
DataSet newDs = new DataSet();
DataTable newDt = tableData.Clone();
newDt.TableName = tableData.TableName+"_" + j;
newDt.Clear();
foreach (DataRow row in tableData.Rows)
{
DataRow newRow = newDt.NewRow();
newRow.ItemArray = row.ItemArray;
newDt.Rows.Add(newRow);
i++;
countOfRows--;
if (i == max )
{
newDs.Tables.Add(newDt);
j++;
newDt = tableData.Clone();
newDt.TableName = tableData.TableName + "_" + j;
newDt.Clear();
i = 0;
}
if (countOfRows == 0 && i < max)
{
newDs.Tables.Add(newDt);
j++;
newDt = tableData.Clone();
newDt.TableName = tableData.TableName + "_" + j;
newDt.Clear();
i = 0;
}
}
return newDs;
}