使用Linq将DataTable分解为固定大小的块的简洁方法是什么?

Mic*_*ren 8 c# linq ienumerable c#-3.0

更新:这是一个类似的问题


假设我有DataTable几千个DataRows.

我想将表拆分成较小行的块进行处理.

我认为C#3改进的数据处理能力可能有所帮助.

这是我到目前为止的骨架:

DataTable Table = GetTonsOfData();

// Chunks should be any IEnumerable<Chunk> type
var Chunks = ChunkifyTableIntoSmallerChunksSomehow; // ** help here! **

foreach(var Chunk in Chunks)
{
   // Chunk should be any IEnumerable<DataRow> type
   ProcessChunk(Chunk);
}
Run Code Online (Sandbox Code Playgroud)

什么应该替换的任何建议ChunkifyTableIntoSmallerChunksSomehow

我真的很感兴趣有人会通过访问C#3工具来做到这一点.如果尝试应用这些工具是不合适的,请解释!


更新3(修改后的块,因为我真的想要表,而不是ienumerables;使用扩展方法 - 感谢雅各布):

最终实施:

处理分块的扩展方法:

public static class HarenExtensions
{
    public static IEnumerable<DataTable> Chunkify(this DataTable table, int chunkSize)
    {
        for (int i = 0; i < table.Rows.Count; i += chunkSize)
        {
            DataTable Chunk = table.Clone();

            foreach (DataRow Row in table.Select().Skip(i).Take(chunkSize))
            {
                Chunk.ImportRow(Row);
            }

            yield return Chunk;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该扩展方法的示例消费者,具有来自临时测试的样本输出:

class Program
{
    static void Main(string[] args)
    {
        DataTable Table = GetTonsOfData();

        foreach (DataTable Chunk in Table.Chunkify(100))
        {
            Console.WriteLine("{0} - {1}", Chunk.Rows[0][0], Chunk.Rows[Chunk.Rows.Count - 1][0]);
        }

        Console.ReadLine();
    }

    static DataTable GetTonsOfData()
    {
        DataTable Table = new DataTable();
        Table.Columns.Add(new DataColumn());

        for (int i = 0; i < 1000; i++)
        {
            DataRow Row = Table.NewRow();
            Row[0] = i;

            Table.Rows.Add(Row);
        }

        return Table;
    }
}
Run Code Online (Sandbox Code Playgroud)

mqp*_*mqp 7

这是非常易读的,只能迭代序列一次,也许可以为您节省重复冗余Skip()/ Take()调用的相当糟糕的性能特征:

public IEnumerable<IEnumerable<DataRow>> Chunkify(DataTable table, int size)
{
    List<DataRow> chunk = new List<DataRow>(size);

    foreach (var row in table.Rows)
    {
        chunk.Add(row);
        if (chunk.Count == size)
        {
            yield return chunk;
            chunk = new List<DataRow>(size);
        }
    }

    if(chunk.Any()) yield return chunk;
}
Run Code Online (Sandbox Code Playgroud)


Jac*_*itt 6

对于Linq的Skip and Take方法来说,这似乎是一个理想的用例,具体取决于你想要通过分块实现的目标.这是完全未经测试的,从未在IDE代码中输入,但您的方法可能看起来像这样.

private List<List<DataRow>> ChunkifyTable(DataTable table, int chunkSize)
{
    List<List<DataRow>> chunks = new List<List<DaraRow>>();
    for (int i = 0; i < table.Rows.Count / chunkSize; i++)
    {
        chunks.Add(table.Rows.Skip(i * chunkSize).Take(chunkSize).ToList());
    }

    return chunks;
}
Run Code Online (Sandbox Code Playgroud)