-3

データベースから大量の Blob データ (300Gb 以上) を読み取り、別のデータベースに挿入する必要があります。次のコードを使用してデータを読み取っています。

if (dr.HasRows)
{
    while (dr.Read())
    {
       media m = new media
       {
           docid = Convert.ToInt32(dr["Id"]),
           Content = Convert.ToByte(dr["BlobData"]),
           madiaName = Convert.ToString(dr["Name"])
       }
    }

    InsertInNewDb(m);
}

行ごとに読み取り、asnother db にデータを挿入しています。問題は、オブジェクトを破棄していないため、一部のデータを送信した後にメモリ不足の例外が生成されることです。単一の反復後にオブジェクトを破棄する方法は?

4

2 に答える 2

1

いくつかの回答とコメントを結び付けるには、次のようにしてみてください。

// The SqlConnection, SqlCommand and SqlDataReader need to be in using blocks
// so that they are disposed in a timely manner. This does not clean  up
// memory, it cleans up unmanaged resources like handles
using (SqlConnection conn = new SqlConnection(connectionString))
{
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM OldTable", conn))
    {
        using (SqlDataReader dr = cmd.ExecuteReader())
        {
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                   media m = new media
                   {
                       // Don't convert - cast instead. These are already the correct
                       // type.
                       docid = (int) dr["Id"],
                       // There are more efficient ways to do this, but
                       // Convert.ToByte was copying only a single byte
                       Content = dr["BlobData"],
                       madiaName = (string)dr["Name"]
                   }

                    // You probably want to insert _all_ of the rows.
                    // Your code was only inserting the last
                    InsertInNewDb(m);
                }
            }
        }
    }
}
于 2013-01-15T02:29:00.187 に答える
0

DataReader のページネーションを試すことができます。これは機能するはずです。いくつかの行の後で、データのソースとターゲットの両方の接続を閉じるようにしてください。メモリをより適切に管理するために、 using命令でオブジェクトを使用することを忘れないでください。

于 2013-01-15T02:01:32.550 に答える