In .Net1.1 ist es nicht sehr praktisch, alle Daten in der gesamten DataTable stapelweise in die Datenbank einzufügen oder zwischen verschiedenen Datenquellen zu migrieren. In .Net2.0 wurden mehrere neue Klassen unter dem SQLClient-Namespace hinzugefügt, um uns bei der stapelweisen Migration von Daten über DataTable oder DataReader zu unterstützen. Die Datenquelle kann aus einer relationalen Datenbank oder XML-Datei oder sogar aus den von WebService zurückgegebenen Ergebnissen stammen. Eine der wichtigsten Klassen ist die SqlBulkCopy-Klasse, die uns leicht dabei helfen kann, Daten von der Datenquelle in die Zieldatenbank zu migrieren.
Lassen Sie uns zunächst die Verwendung dieser Klasse anhand eines einfachen Beispiels veranschaulichen:
DateTime startTime;
protected void Button1_Click(object sender, EventArgs e)
{
startTime = DateTime.Now;
string SrcConString;
string DesConString;
SqlConnection SrcCon = new SqlConnection();
SqlConnection DesCon = new SqlConnection();
SqlCommand SrcCom = new SqlCommand();
SqlDataAdapter SrcAdapter = new SqlDataAdapter();
DataTable dt = new DataTable();
SrcConString =
ConfigurationManager.ConnectionStrings["SrcDBConnectionString"].ConnectionString;
DesConString =
ConfigurationManager.ConnectionStrings["DesDBConnectionString"].ConnectionString;
SrcCon.ConnectionString = SrcConString;
SrcCom.Connection = SrcCon;
SrcCom.CommandText = " SELECT * From [SrcTable]";
SrcCom.CommandType = CommandType.Text;
SrcCom.Connection.Open();
SrcAdapter.SelectCommand = SrcCom;
SrcAdapter.Fill(dt);
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(DesConString,
SqlBulkCopyOptions.UseInternalTransaction);
DesBulkOp.BulkCopyTimeout = 500000000;
DesBulkOp.SqlRowsCopied +=
new SqlRowsCopiedEventHandler(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
versuchen
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
Catch (Ausnahme ex)
{
lblResult.Text = ex.Message;
}
Endlich
{
SrcCon.Close();
DesCon.Close();
}
}
private void OnRowsCopied(object sender, SqlRowsCopiedEventArgs args)
{
lblCounter.Text += args.RowsCopied.ToString() + " Zeilen werden kopiert
";
TimeSpan copyTime = DateTime.Now - startTime;
lblCounter.Text += "Copy Time:" + copyTime.Seconds.ToString() + "." + copyTime.Milliseconds.ToString() + " seconds";
}
Analysieren Sie dann diese Codezeilen im Detail:
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(DesConString, SqlBulkCopyOptions.UseInternalTransaction); Generieren Sie zunächst eine SqlBulkCopy-Instanz. Die Verwendung von SqlBulkCopyOptions.UseInternalTransaction bedeutet, dass die Migrationsaktion in einer Transaktion angegeben wird. Es kommt zu einem Rollback. Weitere Optionen finden Sie im MSDN.
DesBulkOp.BulkCopyTimeout = 500000000;
Geben Sie die Timeout-Zeit für den Abschluss des Vorgangs an.
DesBulkOp.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
versuchen
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
Das NotifyAfter-Attribut gibt die Anzahl der Datenzeilen an, die vor dem Benachrichtigungsereignis verarbeitet werden sollen. Hier wird es als Anzahl der Zeilen in der Tabelle angegeben und das SqlRowsCopied-Ereignis wird hinzugefügt, um die Zeit des gesamten Migrationsprozesses auszugeben. Die WriteToServer-Methode kopiert die Datenquelle in die Zieldatenbank. Bevor Sie die WriteToServer-Methode verwenden, müssen Sie zunächst das Attribut DestinationTableName angeben, bei dem es sich um den Tabellennamen der Zieldatenbank handelt.
Wir können auch selbst eine Transaktion definieren, zum Beispiel:
SqlTransaction Transaction;
Transaktion =
SrcCom.Connection.BeginTransaction();
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(new SqlConnection(DesConString),
SqlBulkCopyOptions.Default,
Transaktion);
versuchen
{
//..
}
fangen{}
Endlich
{
Transaction.Commit();
}
Es gibt auch eine SqlBulkCopyColumnMapping-Klasse, die die Zuordnung von Datenquellenfeldern zu anders benannten Feldern in den Zieldaten ermöglicht. Das heißt, wenn die Spaltennamen der Zieldaten und Quelldaten unterschiedlich sind, können Sie diese Klasse für die Zuordnung verwenden:
SqlBulkCopyColumnMapping ColMap = new SqlBulkCopyColumnMapping("SrcCol", "DesCol");
DesBulkOp.ColumnMappings.Add(ColMap);
Oder Sie können die Zuordnung direkt hinzufügen:
DesBulkOp.ColumnMappings.Add("SrcCol", "DesCol");
Leistungsprobleme:
Ich habe das obige Beispiel verwendet, um etwa 20.000 Datensätze zu testen und zu migrieren. Ich sollte sagen, dass die Leistung immer noch gut ist. Darüber hinaus können Sie bei der Verwendung von SQL Profile zur Überwachung von Migrationsereignissen feststellen, dass nur sehr wenige Anforderungsdatensätze vorhanden sind. Es wird gesagt, dass die Verwendung von SqlBulkCopy die Zeit für die Datenmigration erheblich verkürzen kann.