**更新:**这里有一个similar question
假设我有一个DataTable
,里面有几千个DataRows
。
我想将表拆分为多个较小的行块以进行处理。
我认为C#3改进了处理数据的能力可能会有所帮助。
这是我目前掌握的 backbone :
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);
}
对于ChunkifyTableIntoSmallerChunksSomehow
应该用什么来代替有什么建议吗?
我真的很感兴趣,有人会如何使用访问C#3工具来完成这一点。如果尝试应用这些工具是不合适的,请解释!
更新3(修改了分块,因为我真的想要表,而不是ienumerables;使用扩展方法--谢谢Jacob):
最终实施:
处理分块的扩展方法:
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;
}
}
}
该扩展方法的示例使用者,以及来自特定测试的示例输出:
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;
}
}
6条答案
按热度按时间i34xakig1#
这段代码可读性很强,而且只遍历序列一次,可能会避免重复冗余
Skip()
/Take()
调用所带来的相当糟糕的性能特征:tct7dpnv2#
这看起来是Linq的Skip和Take方法的理想用例,这取决于你想用分块实现什么。这是完全未经测试的,从来没有在IDE代码中输入过,但是你的方法可能看起来像这样。
s6fujrry3#
下面是一个可能奏效的方法:
omqzjyyz4#
雅各布写道
这看起来是Linq的Skip和Take方法的理想用例,这取决于你想用分块实现什么。这是完全未经测试的,从来没有在IDE代码中输入过,但是你的方法可能看起来像这样。
谢谢Jacob-对我很有用,但是我认为你的例子中的测试应该是〈= not〈。如果你使用〈并且行数小于 * chunkSize *,那么循环就不会进入。同样的,最后一个部分块也不会被捕获,只有完整的块。正如你所说的,这个例子是未经测试的,等等,所以这只是一个提示,以防别人逐字使用你的代码; -)
kmpatx3s5#
这里有一个完全不同的方法,没有为块分配内存。
用法示例:
rryofs0p6#
.NET(Core)6引入了Chunk扩展方法,可用于轻松地将DataTable拆分为多个批:
在早期版本MoreLINQ's Batch中,扩展方法也可用于执行相同操作:
这两种方法都可以用来将DataTable拆分为更小的单元。下面的扩展方法使用
LoadRows
帮助器来提取行加载代码,从而实现这一目的:ArgumentNullException.ThrowIfNull(source);
是.NET核心的另一个附加功能,如果参数为空,则使用参数名抛出ArgumentNullException
。最后,
chunkTable.MinimumCapacity = size;
用于为每个表的行保留空间,以避免重新分配