以块的形式枚举DataTable

时间:2012-04-25 16:02:09

标签: c# datatable ado.net

我有一个DataTable,它填满了360,000行SQL数据(这是预期的)。然而,这会遇到OOM问题。

这就是我所拥有的,但是,我不确定如何在1000的最后一个间隔之后处理everthing。或者可能有更好的方法

int catchInt = 0;
string combineWhereClause = string.Empty;

for (int i = 0; i < ThousandLoopTable.Rows.Count; i++)
{
    catchInt++;
    combineWhereClause = combineWhereClause + 
                        "','" + 
                         ThousandLoopTable.Rows[i].ItemArray[0].ToString();

    if (catchInt >= 1000)
    {
        catchInt = 0;
        combineWhereClause = combineWhereClause.TrimStart('\'');
        combineWhereClause = combineWhereClause.TrimStart(',');

        Directory.CreateDirectory(ExportDirectory);
        SQLProcessing.SQLProcessor.MasterSqlConnection = 
            SQLProcessing.SQLProcessor.OpenMasterSqlConnection(SQLServer);
        DataTable dtTable = 
            SQLProcessing.SQLProcessor.QueryDataTable(sql_selectionquery);
        for (int m = 0; m < dtTable.Rows.Count; m++)
        {
            string FileName = dtTable.Rows[m].ItemArray[0].ToString() + ".txt";
            string OCR = dtTable.Rows[m].ItemArray[1].ToString();
            File.AppendAllText(ExportDirectory + "\\" + FileName, OCR);

        }

        combineWhereClause = string.Empty;
    }
}

因此,例如,如果有3120行,这将做3000,但不会做最后120.但是,我不知道如何处理最后120,因为我真的不想这样做for loop我呢?

3 个答案:

答案 0 :(得分:2)

考虑使用Take / Skip方法使用LINQ to SQL。

答案 1 :(得分:2)

您可以遵循简单的规则以避免OutOfMemory异常:

<强>从不

  1. 使用整个数据集
  2. 将整个数据集加载到内存
  3. 执行阻止服务器端数据库的长期事务代码
  4. 始终

    1. 使用小块数据
    2. 加载小块数据(分页模式)
    3. 运行非阻止服务器代码
    4. 如果可以在服务器上执行任何操作,请让它完成工作
    5. 确保服务器上的数据不可变(没有人更改它)。如果无法保证这一点,您可能需要重新考虑您的体系结构并使用队列和其他表来处理数据。

答案 2 :(得分:0)

可能有更好的方法来处理数据(请参阅其他答案),但我认为这是您当前方法所需要的:

不要为每个批次重置catchInt。相反,将其初始化为1并让它作为整个操作的计数器运行。然后将if更改为:

if (catchInt % 1000 == 0 || catchInt == ThousandLoopTable.Rows.Count)
{
    // Execute your batch
}

这使用Modulus operator来确定何时catchInt可被1000整除。