Как разбить или разделить 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 &lt;= batchSize)
        {
            new_table.TableName = "Table_" + k;
            new_table = originalTable.Copy();
            tables.Add(new_table.Copy());
        }
        else
        {
            for (int i = 0; i &lt; 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;
        }