C# 批量高效枚举数据表行

C# 批量高效枚举数据表行,c#,.net,ado.net,datatable,C#,.net,Ado.net,Datatable,我想分批枚举一个数据表。为此,我创建了一个返回IEnumerable的方法,该方法如下所示: public IEnumerable<DataTable> EnumerateRowsInBatches( DataTable table, int batchSize ) { int rowCount = table.Rows.Count; int batchIndex = 0; while( batchIndex * batchSize < rowCoun

我想分批枚举一个数据表。为此,我创建了一个返回
IEnumerable
的方法,该方法如下所示:

public IEnumerable<DataTable> EnumerateRowsInBatches( DataTable table, int batchSize ) {

    int rowCount = table.Rows.Count;
    int batchIndex = 0;
    while( batchIndex * batchSize < rowCount ) {
        DataTable result = table.Clone();
        int batchStart = batchIndex * batchSize;
        int batchLimit = ( batchIndex + 1 ) * batchSize;
        if( rowCount < batchLimit )
            batchLimit = rowCount;
        for( int i = batchStart; i < batchLimit; i++ ) {
            result.ImportRow( table.Rows[ i ] );
        }
        batchIndex++;
        yield return result;
    }
}
public IEnumerable EnumerateRowsInBatchs(数据表,int-batchSize){
int rowCount=table.Rows.Count;
int batchIndex=0;
while(batchIndex*batchSize
事实上,这很有效。我正在迭代这些批处理,以便使用表值参数发送到SQL Server。但是我看到,
ImportRow
占用了大部分时间,我想加快速度


我在寻找如何做到这一点。我可以自由地将所有数据视为只读数据,因此我觉得在这里复制行并不是绝对必要的。

我提出了一种方法,可以在测试中提高约40%的性能:

public static IEnumerable<DataTable> EnumerateRowsInBatches(DataTable table,
                                                            int batchSize)
{
    int rowCount = table.Rows.Count;
    int batchIndex = 0;
    DataTable result = table.Clone(); // This will not change, avoid recreate it
    while (batchIndex * batchSize < rowCount)
    {
        result.Rows.Clear(); // Reuse that DataTable, clear previous results
        int batchStart = batchIndex * batchSize;
        int batchLimit = (batchIndex + 1) * batchSize;
        if (rowCount < batchLimit)
            batchLimit = rowCount;

        for (int i = batchStart; i < batchLimit; i++)
            result.Rows.Add(table.Rows[i].ItemArray); // Avoid ImportRow

        batchIndex++;
        yield return result;
    }
}
公共静态IEnumerable EnumerateRowsInBatches(数据表,
int批处理大小)
{
int rowCount=table.Rows.Count;
int batchIndex=0;
DataTable结果=table.Clone();//这不会更改,请避免重新创建它
while(batchIndex*batchSize
我提出了一种方法,使我的测试性能提高了约40%:

public static IEnumerable<DataTable> EnumerateRowsInBatches(DataTable table,
                                                            int batchSize)
{
    int rowCount = table.Rows.Count;
    int batchIndex = 0;
    DataTable result = table.Clone(); // This will not change, avoid recreate it
    while (batchIndex * batchSize < rowCount)
    {
        result.Rows.Clear(); // Reuse that DataTable, clear previous results
        int batchStart = batchIndex * batchSize;
        int batchLimit = (batchIndex + 1) * batchSize;
        if (rowCount < batchLimit)
            batchLimit = rowCount;

        for (int i = batchStart; i < batchLimit; i++)
            result.Rows.Add(table.Rows[i].ItemArray); // Avoid ImportRow

        batchIndex++;
        yield return result;
    }
}
公共静态IEnumerable EnumerateRowsInBatches(数据表,
int批处理大小)
{
int rowCount=table.Rows.Count;
int batchIndex=0;
DataTable结果=table.Clone();//这不会更改,请避免重新创建它
while(batchIndex*batchSize
您不使用
result.Rows.Add的具体原因是什么?还是不使用的原因?@DanielHilgarth不太清楚。我得经常打电话给你,对吗?这是否表现得更好(我必须对其进行测量)。对于奇怪的结果,Rows.Add将给出System.ArgumentException:“这一行已经属于另一个表。”(cc@DanielHilgarth)@RubensFarias我不得不不同意你的观点。TVP的性能通常比分解xml参数要好得多。您不使用
result.Rows.Add
,是有具体原因吗?还是有不使用的原因?@DanielHilgarth不太清楚。我得经常打电话给你,对吗?这是否表现得更好(我必须对其进行测量)。对于奇怪的结果,Rows.Add将给出System.ArgumentException:“这一行已经属于另一个表。”(cc@DanielHilgarth)@RubensFarias我不得不不同意你的观点。TVP的性能通常比分解xml参数要好得多。对于OP来说,这应该是可行的,但在某些其他情况下,重新使用同一个表并清除行可能会导致不良结果。您有这种情况的示例吗,@JoelCoehoorn?比较此代码段中的两个表:
var tables=EnumerateRowsInBatches(…).Take(2).ToList()该代码反复返回对同一对象的引用。每个点的状态都不同,但是如果您等到枚举之后才查看任何结果,则每个项都是相同的,并且应该与枚举的最后一项匹配。是的,这看起来很有希望。在我的情况下,性能增益可能值得在灵活性或健壮性之间进行权衡。这应该符合OP的目的,但在某些其他情况下,重复使用同一个表和清除行可能会导致糟糕的结果。您有这种情况的示例吗,@JoelCoehoorn?比较这段代码中的两个表:
var tables=EnumerateRowsInBatches(…).Take(2.ToList()该代码反复返回对同一对象的引用。每个点的状态都不同,但是如果您等到枚举之后才查看任何结果,则每个项都是相同的,并且应该与枚举的最后一项匹配。是的,这看起来很有希望。在我的例子中,性能提升可能值得在灵活性和健壮性之间进行权衡。