2

360,000行のSQLデータでいっぱいになるDataTableがあります(これは意図されたものです)。ただし、これはOOMの問題に遭遇します。

これは私が持っているものですが、最後の1000の間隔の後、すべてを処理する方法がわかりません。または、より良い方法があるかもしれません

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は実行しません。ただし、forループで実行したくないので、最後の120を処理する方法がわかりません。私?

4

3 に答える 3

2

Take / SkipメソッドでLINQtoSQLを使用することを検討してください。

于 2012-04-25T16:05:07.777 に答える
2

OutOfMemory例外を回避するために従うことができる簡単なルールがあります。

一度もない

  1. データセット全体を操作する
  2. データセット全体をメモリにロードする
  3. サーバー側のデータベースをブロックする実行時間の長いトランザクションコードを実行する

いつも

  1. データの小さなチャンクを処理する
  2. データの小さなチャンクをロードする(ページネーションパターン)
  3. ノンブロッキングサーバーコードを実行する
  4. サーバーで何かできることがあれば、サーバーに任せてください

サーバー上のデータが変更可能でないことを確認してください(誰もデータを変更していません)。これを保証できない場合は、アーキテクチャを再考し、処理されたデータにキューと追加のテーブルを使用する必要があります。

于 2012-04-25T16:17:28.630 に答える
0

データを処理するためのより良い方法はおそらくありますが(他の回答を参照)、これが現在のアプローチに必要なものだと思います。

catchIntバッチごとにリセットしないでください。代わりに、として初期化し1、操作全体のカウンターとして実行させます。次に、を次のように変更ifします。

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

これは、モジュラス演算子catchIntを使用して、が1000で割り切れるときを識別します。

于 2012-04-25T16:40:11.080 に答える