Home > other >  How to divide DataTable to multiple DataTables by row index
How to divide DataTable to multiple DataTables by row index

Time:12-30

I have one DataTable that i need to split into multiple DataTables, with the same structure, by rows. The way i need to split the tables is: if i have a table with 40 rows, each individual new table can have a maximum of 17 rows. So it should be first DataTable with rows 1-17, second from 18-34 and third from 35 to 40. Finally, i would add the mentioned tables to the DataSet.

I tried creating copies of the tables and deleting rows by index, but that didn't work.

CodePudding user response:

you can use table.AsEnumerable() and use Skip(startRowIndex) for start index of rows and take(size) for size of each table...

var t1 = table.AsEnumerable().Skip(0).Take(17).CopyToDataTable();
var t2 = table.AsEnumerable().Skip(17).Take(17).CopyToDataTable();
...

CodePudding user response:

A reusable way that handles cases like empty tables or tables that contain less rows than the split-count is this method:

public static IEnumerable<DataTable> SplitTable(DataTable table, int splitCount)
{
    if (table.Rows.Count <= splitCount) 
    {
        yield return table.Copy(); // always create a new table
        yield break;
    }

    for (int i = 0; i   splitCount <= table.Rows.Count; i  = splitCount)
    {
        yield return CreateCloneTable(table, i, splitCount);
    }

    int remaining = table.Rows.Count % splitCount;
    if (remaining > 0)
    {
        yield return CreateCloneTable(table, table.Rows.Count - remaining, splitCount);
    }
}

private static DataTable CreateCloneTable(DataTable mainTable, int startIndex, int length)
{
    DataTable tClone = mainTable.Clone(); // empty but same schema
    for (int r = startIndex; r < Math.Min(mainTable.Rows.Count, startIndex   length); r  )
    {
        tClone.ImportRow(mainTable.Rows[r]);
    }

    return tClone;
}

Here is your case with 40 rows and 17 split-count:

DataTable table = new DataTable();
table.Columns.Add();
for (int i = 1; i <= 40; i  ) table.Rows.Add(i.ToString());
DataSet ds = new DataSet();
ds.Tables.AddRange(SplitTable(table, 17).ToArray());

Demo: https://dotnetfiddle.net/8XUBjH

CodePudding user response:

you can create a DataSet and add multiple tables to it in the batch size of 17 in your case.

DataSet dataSet = new DataSet();
int batchSize = 17;

DataTable currentDT = originalTable.Clone();

for (int i = 0; i < originalTable.Rows.Count; i  )
{
    currentDT.Rows.Add(originalTable.Rows[i].ItemArray);

    // add to DatSet
    if (currentDT.Rows.Count == batchSize)
    {
        dataSet.Tables.Add(currentDT);
        currentDT = originalTable.Clone();
    }
}

// Add any remaining rows to the DataSet
if (currentDT.Rows.Count > 0)
{
    dataSet.Tables.Add(currentDT);
}
  • Related