Di .Net1.1, sangat tidak nyaman untuk memasukkan semua data di seluruh DataTable ke dalam database atau melakukan migrasi antar sumber data yang berbeda. Di .Net2.0, beberapa kelas baru telah ditambahkan di bawah namespace SQLClient untuk membantu kami memigrasikan data secara batch melalui DataTable atau DataReader. Sumber data bisa berasal dari database relasional atau file XML, atau bahkan hasil yang dikembalikan oleh WebService. Salah satu kelas yang paling penting adalah kelas SqlBulkCopy, yang dapat dengan mudah membantu kita memigrasikan data dari sumber data ke database target.
Pertama mari kita ilustrasikan penggunaan kelas ini melalui contoh sederhana:
TanggalWaktu mulaiWaktu;
void yang dilindungi Button1_Click(pengirim objek, EventArgs e)
{
startTime = DateTime.Sekarang;
string SrcConString;
string DesConString;
SqlConnection SrcCon = SqlConnection baru();
SqlConnection DesCon = SqlConnection baru();
SqlCommand SrcCom = baru SqlCommand();
SqlDataAdapter SrcAdapter = baru SqlDataAdapter();
DataTable dt = DataTable baru();
SrcConString =
ConfigurationManager.ConnectionStrings["SrcDBConnectionString"].ConnectionString;
DesConString =
ConfigurationManager.ConnectionStrings["DesDBConnectionString"].ConnectionString;
SrcCon.ConnectionString = SrcConString;
SrcCom.Koneksi = SrcCon;
SrcCom.CommandText = " PILIH * Dari [SrcTable]";
SrcCom.CommandType = CommandType.Teks;
SrcCom.Koneksi.Buka();
SrcAdapter.SelectCommand = SrcCom;
SrcAdapter.Isi(dt);
SqlBulkSalin DesBulkOp;
DesBulkOp = SqlBulkCopy baru(DesConString,
SqlBulkCopyOptions.UseInternalTransaction);
DesBulkOp.BulkCopyTimeout = 500000000;
DesBulkOp.SqlRowsDisalin +=
SqlRowsCopiedEventHandler baru(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
mencoba
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
menangkap (Pengecualian ex)
{
lblResult.Teks = ex.Pesan;
}
Akhirnya
{
SrcCon.Tutup();
DesCon.Tutup();
}
}
private void OnRowsCopied (pengirim objek, argumen SqlRowsCopiedEventArgs)
{
lblCounter.Text += args.RowsCopied.ToString() + " baris disalin<Br>";
TimeSpan copyTime = DateTime.Sekarang - startTime;
lblCounter.Text += "Waktu Penyalinan:" + copyTime.Seconds.ToString() + "." + copyTime.Milliseconds.ToString() + " detik";
}
Kemudian analisis baris kode ini secara detail:
SqlBulkSalin DesBulkOp;
DesBulkOp = new SqlBulkCopy(DesConString, SqlBulkCopyOptions.UseInternalTransaction); Pertama, buat instance SqlBulkCopy. Konstruktor menentukan database target. Menggunakan SqlBulkCopyOptions.UseInternalTransaction berarti tindakan migrasi ditentukan dalam Transaksi. kemunduran akan terjadi. Silakan merujuk ke MSDN untuk opsi lainnya.
DesBulkOp.BulkCopyTimeout = 500000000;
Tentukan waktu Timeout untuk penyelesaian operasi
DesBulkOp.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
mencoba
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
Atribut NotifyAfter menentukan jumlah baris data yang akan diproses sebelum peristiwa notifikasi. Di sini, atribut ini ditentukan sebagai jumlah baris dalam tabel, dan peristiwa SqlRowsCopied ditambahkan untuk menampilkan waktu seluruh proses migrasi. Metode WriteToServer menyalin sumber data ke database target. Sebelum menggunakan metode WriteToServer, Anda harus menentukan terlebih dahulu atribut DestinationTableName, yang merupakan nama tabel dari database target.
Kita juga dapat mendefinisikan sendiri suatu Transaksi, misalnya:
SqlTransaction Transaction;
Transaksi =
SrcCom.Koneksi.BeginTransaction();
SqlBulkSalin DesBulkOp;
DesBulkOp = SqlBulkCopy baru(SqlConnection baru(DesConString),
SqlBulkCopyOptions.Bawaan,
Transaksi);
coba
{
//..
}
menangkap{}
Akhirnya
{
Transaksi.Komit();
}
Ada juga kelas SqlBulkCopyColumnMapping yang memungkinkan bidang sumber data dipetakan ke bidang dengan nama berbeda di data target. Artinya, jika nama kolom data target dan data sumber berbeda, Anda bisa menggunakan kelas ini untuk pemetaan:
SqlBulkCopyColumnMapping ColMap = new SqlBulkCopyColumnMapping("SrcCol", "DesCol");
DesBulkOp.ColumnMappings.Add(ColMap);
Atau Anda dapat menambahkan pemetaan secara langsung:
DesBulkOp.ColumnMappings.Add("SrcCol", "DesCol");
Masalah kinerja:
Saya menggunakan contoh di atas untuk menguji dan memigrasikan sekitar 20.000 catatan. Hanya butuh waktu kurang dari satu detik. Selain itu, dengan menggunakan Profil SQL untuk memantau peristiwa migrasi, Anda dapat melihat bahwa catatan permintaan sangat sedikit, hanya sedikit. Dikatakan bahwa penggunaan SqlBulkCopy dapat sangat mengurangi waktu migrasi data.