Ich verwende SQLBulkCopy, um große Datenmengen zu verschieben. Ich habe das Benachrichtigungsereignis implementiert, um mich jedes Mal zu benachrichtigen, wenn eine bestimmte Anzahl von Zeilen verarbeitet wurde, aber das OnSqlRowsCopied-Ereignis wird nicht ausgelöst, wenn der Job abgeschlossen ist. Wie bekomme ich die Gesamtzahl der Zeilen, die beim Abschluss des SQLBulkCopy-Schreibserviceservers kopiert werden?SQLBulkCopy Zeilenanzahl nach Abschluss
Antwort
Ich denke, Sie müssen eine COUNT() Abfrage auf der Tabelle nach dem Beenden ausführen, wie in dem MSDN-Beispiel here.
Anders als das, können Sie nicht sagen, vorne? z.B. Wenn Sie eine DataTable an WriteToServer() übergeben, wissen Sie, wie viele Datensätze ausgeführt werden, indem Sie eine .Rows.Count ausführen.
die folgende Hack (mit Reflexion) ist eine Option:
/// <summary>
/// Helper class to process the SqlBulkCopy class
/// </summary>
static class SqlBulkCopyHelper
{
static FieldInfo rowsCopiedField = null;
/// <summary>
/// Gets the rows copied from the specified SqlBulkCopy object
/// </summary>
/// <param name="bulkCopy">The bulk copy.</param>
/// <returns></returns>
public static int GetRowsCopied(SqlBulkCopy bulkCopy)
{
if (rowsCopiedField == null)
{
rowsCopiedField = typeof(SqlBulkCopy).GetField("_rowsCopied", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
}
return (int)rowsCopiedField.GetValue(bulkCopy);
}
}
Und dann die Klasse wie folgt verwenden:
int rowsCopied = SqlBulkCopyHelper.GetRowsCopied(bulkCopyObjectInYourCode);
Hoffnung, das hilft.
Warum nicht eine Erweiterungsmethode? public static int GetRowsCopied (diese SqlBulkCopy-BulkCopy) – mhenry1384
Meine einzige Sorge hier ist, dass es ein internes Feld bekommt und nicht mit der öffentlichen API spielt. Dieses interne Feld könnte sich in einer zukünftigen Implementierung ändern, ohne die API zu unterbrechen, und das würde diesen Code durchbrechen. (Es ist unwahrscheinlich, aber es ist möglich, und ich habe so etwas schon einmal gesehen.) Aus genau diesem Grund ist es gefährlich, auf private Felder zuzugreifen - es könnte heute funktionieren, aber es gibt keine Garantie, dass es funktioniert Morgen. (Es wäre wirklich schön gewesen, wenn Microsoft hier eine öffentliche Immobilie bloßgestellt hätte.) –
Der Vollständigkeit halber habe ich als eine Erweiterungsmethode implementiert und den Namespace enthalten. Kopieren und fügen Sie diese Klasse ein, wenn Sie eine schnelle Lösung benötigen, um die kopierte Anzahl zu erhalten. Hinweis: Diese Anzahl berücksichtigt nicht die Anzahl der Zeilen, die tatsächlich eingefügt werden, wenn Duplikate ignorieren auf EIN gesetzt ist.
namespace System.Data.SqlClient
{
using Reflection;
public static class SqlBulkCopyExtension
{
const String _rowsCopiedFieldName = "_rowsCopied";
static FieldInfo _rowsCopiedField = null;
public static int RowsCopiedCount(this SqlBulkCopy bulkCopy)
{
if (_rowsCopiedField == null) _rowsCopiedField = typeof(SqlBulkCopy).GetField(_rowsCopiedFieldName, BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
return (int)_rowsCopiedField.GetValue(bulkCopy);
}
}
}
Durch die Verwendung von SqlBulkCopy.SqlRowsCopied Event
(Tritt jedes Mal, dass die Anzahl der Zeilen, die von der NotifyAfter
Eigenschaft angegeben verarbeitet worden ist) können wir SqlBulkCopy Zeilenanzahl erreichen, wenn Sie fertig.
using (SqlBulkCopy s = new SqlBulkCopy(db.Database.Connection as SqlConnection))
{
s.SqlRowsCopied += new SqlRowsCopiedEventHandler(sqlBulk_SqlRowsCopied);
s.BatchSize = csvFileData.Rows.Count;//DataTable
s.NotifyAfter = csvFileData.Rows.Count;
foreach (var column in csvFileData.Columns)
s.ColumnMappings.Add(column.ToString(), column.ToString());
// Set the timeout.
s.BulkCopyTimeout = 60;
s.DestinationTableName = "Employee_Data";
s.WriteToServer(csvFileData);
}
private static void sqlBulk_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
{
long Count = e.RowsCopied;
}
Hier ist, was ich tat - es ist eine leichte Modifikation der Lösung von Rahul Modi in diesem Thread (im Grunde ist es setzt nur das Ereignis Inline SqlRowsCopied, was meiner Meinung nach einem bisschen sauberer ist in diesem Fall als die neuen Event-Handler zu schaffen Methode):
private long InsetData(DataTable dataTable, SqlConnection connection)
{
using (SqlBulkCopy copier = new SqlBulkCopy(connection))
{
var filesInserted = 0L;
connection.Open();
copier.DestinationTableName = "dbo.MyTable";
copier.NotifyAfter = dataTable.Rows.Count;
copier.SqlRowsCopied += (s, e) => filesInserted = e.RowsCopied;
copier.WriteToServer(dataTable);
connection.Close();
return filesInserted;
}
}
- 1. Drucken nach n Zeilenanzahl stoppen
- 2. Status ändern nach Abschluss
- 3. Flackern nach Abschluss Aktivität
- 4. Argumentstatus nach Abschluss des Threads
- 5. Rückgabewert nach Abschluss der Funktion
- 6. Rückruf nach Abschluss der Methode
- 7. warten Aufgabe nicht nach Abschluss
- 8. Ansicht unbrauchbar nach ablehnenViewControllerAnimated: Abschluss:
- 9. Erfolgsmeldung nach Abschluss jsonfile npm
- 10. CSS-Stop-Animation nach Abschluss des Fortschrittsbalkens
- 11. Prune zurück Geschichte nach Tätigkeit Abschluss
- 12. Begrenzen der IntelliJ IDEA-Importvorschläge nach Abschluss
- 13. Abschluss der Objektkonstruktion nach der GSON-Deserialisierung
- 14. Refreshing UI nach der parallelen Verarbeitung Abschluss
- 15. Tabelle Sperre nach Integrität Wartung Abschluss
- 16. NSURLConnection senden Anfrage nach Abschluss aller Prozess
- 17. Unity - Rückgabewert erst nach Abschluss der Koroutine
- 18. Schließen Realm-Instanz nach Abschluss der Ausführung
- 19. Abspielen von Audio nach Abschluss der Aktivitätsübergabe
- 20. Herunterfahren PC nach Abschluss eines Skripts
- 21. Python - Schließen Firefox-Browser nach Abschluss
- 22. EditText Fokus geht nicht nach Abschluss Aktivität
- 23. NSIS, Fortschrittsbalken zeigt nach Abschluss keine 100%
- 24. Benachrichtigung verschwinden nach Abschluss der Aktivität
- 25. Pandas: Speichern "Zeilenanzahl"
- 26. Gute Praxis Klasse Zeilenanzahl
- 27. Abschneiden vor SqlBulkCopy
- 28. Wie funktioniert SqlBulkCopy
- 29. Million Einsätze: SqlBulkCopy Timeout
- 30. SqlBulkCopy mit verschiedenen Sortierungen
und wenn Sie eine IDataReader verwenden, können Sie es einfach wickeln, sollte es nie wirklich einen Bedarf zählen, sondern es ist ein Hack zu nennen, die –
@ Sam arbeiten, Wie es Sie bedeuten „wrap "? Ich habe eine 'SqlDataReader', und die nächste Sache einer Zeilenzählung ist die' RecordsAffected' -Eigenschaft, die in diesem Fall immer -1 ist. – chezy525
Dies ist die sicherere Methode als die unten aufgeführten (die zugegebenermaßen sind , glatt!) - Der Zugriff auf ein privates Feld könnte in der Zukunft ohne Warnung unterbrochen werden (Microsoft könnte die Implementierung einer öffentlichen API ändern, ohne die öffentliche API zu ändern, indem Feldnamen geändert werden), die Anzahlabfrage funktioniert jedoch weiterhin. –