Używam SQLBulkCopy do przenoszenia dużych ilości danych. Zaimplementowałem powiadomienie, aby powiadomić mnie za każdym razem, gdy przetwarzana jest pewna liczba wierszy, ale zdarzenie OnSqlRowsCopied nie uruchamia się po zakończeniu zadania. Jak uzyskać całkowitą liczbę wierszy skopiowanych po ukończeniu skryptu skryptowego SQLBulkCopy?Liczba wierszy SQLBulkCopy po ukończeniu
Odpowiedz
Myślę, że po zakończeniu należy uruchomić zapytanie COUNT(), tak jak w przykładzie MSDN here.
Poza tym, nie możesz powiedzieć z przodu? na przykład jeśli przekazujesz DataTable do WriteToServer(), wtedy wiesz ile rekordów wykonujesz na .Rows.Count na tym.
Poniższa Hack (przy użyciu odbicia) jest opcją:
/// <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);
}
}
A następnie użyć klasy następująco:
int rowsCopied = SqlBulkCopyHelper.GetRowsCopied(bulkCopyObjectInYourCode);
nadzieję, że to pomaga.
Dlaczego nie uczynić tego metodą rozszerzenia? public static int GetRowsCopied (this SqlBulkCopy bulkCopy) – mhenry1384
Moim jedynym zmartwieniem jest to, że dostaje wewnętrzne pole i nie gra z publicznym API. To wewnętrzne pole może się zmienić w przyszłej implementacji bez łamania API, a to by złamało ten kod. (Może się to wydawać mało prawdopodobne, ale jest to możliwe, i widziałem już takie rzeczy.) To właśnie jest niebezpieczny dostęp do prywatnych pól z tego właśnie powodu - może zadziałać dzisiaj, ale nie ma gwarancji, że zadziała. jutro. (Naprawdę byłoby miło, gdyby Microsoft właśnie ujawnił tutaj publiczną własność). –
Dla kompletności zaimplementowałem jako metodę rozszerzenia i zawarłem przestrzeń nazw. Skopiuj i wklej tę klasę, jeśli chcesz szybkiego rozwiązania, aby uzyskać skopiowaną liczbę. Uwaga: ta liczba nie uwzględnia liczby wierszy faktycznie wstawionych, gdy opcja Ignore Duplicates jest ustawiona na ON.
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);
}
}
}
Korzystając SqlBulkCopy.SqlRowsCopied Event
(występują za każdym razem, że liczba wierszy podanych przez obiekt NotifyAfter
zostały przetworzone) możemy osiągnąć SQLBulkCopy Row liczyć po zakończeniu.
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;
}
Oto co zrobiłem - to niewielka modyfikacja rozwiązania Rahul Modi w tym wątku (w zasadzie to właśnie stawia inline zdarzeń SqlRowsCopied, co moim zdaniem jest nieco czystsze w tym przypadku niż tworzenie nowego obsługi zdarzeń metoda):
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. Ustawienie etykieta tekst po ukończeniu bloku Swift
- 2. Funkcja połączenia po ukończeniu slidetoggle kompletna
- 3. Jak wydrukować tekst po ukończeniu zadania?
- 4. TransitionDrawable: automatyczne przejście do tyłu po ukończeniu
- 5. Przygotowane instrukcje - liczba wierszy
- 6. Liczba wierszy w RDD
- 7. liczba liczba wierszy w szablonach kolby
- 8. Widoczna liczba wierszy obiektu TextBlock
- 9. SQL DELETE - Maksymalna liczba wierszy
- 10. Liczba wierszy w arkuszu roboczym
- 11. Liczba wierszy w każdej grupie
- 12. Liczba wierszy w tablicy numpy
- 13. Liczba wierszy w pliku CSV
- 14. Liczba wierszy SQL w tabeli
- 15. Liczba wierszy Matlaba w pliku Excel
- 16. Liczba wierszy, w której istnieją dane
- 17. Dynamiczna liczba wierszy w Laravel Blade
- 18. Maksymalna liczba wierszy w tabeli sqlite?
- 19. Liczba wierszy rodziny kolumn w Cassandra
- 20. MYSQL - liczba wierszy w każdej tabeli
- 21. Liczba wierszy na grupę w mysql
- 22. Liczba wierszy hibernacji z pewnymi kryteriami:
- 23. Nieprawidłowa aktualizacja: nieprawidłowa liczba wierszy w sekcji
- 24. Liczba grupy według wierszy w hibernacji kryteriów
- 25. SqlBulkCopy - Nieoczekiwany istniejący transakcja
- 26. Milion wkładki: SqlBulkCopy Timeout
- 27. Uzyskiwanie pustych wierszy po ustawieniu DataGridView.DataSource
- 28. Pomiń niektóre kolumny w SqlBulkCopy
- 29. sqlbulkcopy przy użyciu sql CE
- 30. Aktualizacja widoku tabeli "NSInternalInconsistencyException", powód: "Nieprawidłowa aktualizacja: nieprawidłowa liczba wierszy?
a jeśli używasz IDataReader można po prostu zawinąć go, nie powinno nigdy być naprawdę potrzeba, aby zadzwonić count ale jego hack, który może pracować –
@Sam, jaki masz na myśli „owinąć "? Mam 'SqlDataReader', a najbliżej liczby wierszy ma właściwość' RecordsAffected', która jest zawsze -1 w tym przypadku ... – chezy525
To jest bezpieczniejsza metoda niż te wymienione poniżej (które są, co prawda, , gładko!) - dostęp do prywatnego pola może przerwać się w przyszłości bez ostrzeżenia (Microsoft mógłby zmienić implementację publicznego interfejsu API bez przerywania publicznego interfejsu API poprzez zmianę nazw pól), ale zapytanie liczenia wciąż działałoby. –