J'utilise SQLBulkCopy pour déplacer de grandes quantités de données. J'ai implémenté l'événement de notification pour me notifier chaque fois qu'un certain nombre de lignes ont été traitées, mais l'événement OnSqlRowsCopied ne se déclenche pas lorsque le travail est terminé. Comment puis-je obtenir le nombre total de lignes copiées lorsque le writetoserver SQLBulkCopy est terminé?Nombre de lignes SQLBulkCopy une fois rempli
Répondre
Je pense que vous devez exécuter une requête COUNT() sur la table après avoir terminé, comme dans l'exemple MSDN here.
À part ça, vous ne pouvez pas dire au premier plan? par exemple. Si vous passez un DataTable à WriteToServer() alors vous savez combien d'enregistrements en faisant un .Rows.Count dessus.
Le hack (utilisant la réflexion) est une 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);
}
}
Et puis utilisez la classe comme suit:
int rowsCopied = SqlBulkCopyHelper.GetRowsCopied(bulkCopyObjectInYourCode);
Hope this helps.
Pourquoi ne pas en faire une méthode d'extension? public static int GetRowsCopied (ce bulkCopy SqlBulkCopy) – mhenry1384
Ma seule préoccupation ici est qu'il obtient un champ interne et ne joue pas avec l'API publique. Ce champ interne pourrait changer dans une future implémentation sans casser l'API, et cela casserait ce code. (C'est peut-être improbable, mais c'est possible, et j'ai vu des choses comme ça avant.) Il est dangereux d'accéder à des champs privés pour cette raison - cela pourrait fonctionner aujourd'hui, mais il n'y a aucune garantie que cela fonctionne demain. (Vraiment, ça aurait été bien si Microsoft venait d'exposer une propriété publique ici.) –
Pour être complet, j'ai implémenté comme méthode d'extension et inclus l'espace de noms. Copiez et collez cette classe si vous voulez une solution rapide pour obtenir le nombre copié. Remarque: Ce nombre ne prend pas en compte le nombre de lignes réellement insérées lorsque Ignorer les doublons est défini sur 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);
}
}
}
En utilisant SqlBulkCopy.SqlRowsCopied Event
(produit chaque fois que le nombre de lignes spécifié par la propriété NotifyAfter
a été traitée), nous pouvons obtenir SqlBulkCopy Row Count une fois terminé.
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;
}
Voici ce que je l'ai fait - c'est une légère modification de la solution de Rahul Modi dans ce fil (fondamentalement, il met juste la ligne d'événement SqlRowsCopied, qui je pense est un peu plus propre dans ce cas que la création du nouveau gestionnaire d'événements méthode):
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. Les avis de conception sont-ils utiles une fois le code rempli?
- 2. Aide sur les requêtes SQL: sélection des lignes qui apparaissent un certain nombre de fois
- 3. Obtenir le nombre de lignes avec une requête GROUP BY
- 4. Déterminer le nombre de lignes dans une plage
- 5. Nombre de lignes affectées par une UPDATE en PL/SQL
- 6. Nombre maximal de lignes dans une table sqlite
- 7. Nombre de lignes visibles d'un TextBlock
- 8. Truncate before SqlBulkCopy
- 9. Quel est l'inconvénient de SqlBulkCopy
- 10. Nombre de lignes MVC Contrib Grid
- 11. SQL CLR SqlBulkCopy from DataTable
- 12. GL_POLYGON n'est pas rempli correctement?
- 13. Utilisation de named_scope pour obtenir le nombre de lignes
- 14. erreur insertion de données à l'aide SqlBulkCopy
- 15. regex: expression correspondant même nombre inconnu de fois
- 16. SqlBulkCopy dans la table avec la clé primaire composite
- 17. Comment extraire une seule colonne de données d'un DataSet rempli?
- 18. Existe-t-il un moyen d'avoir une capture répète un nombre arbitraire de fois dans une regex?
- 19. TSQL pour obtenir le nombre suivant de lignes de données?
- 20. Nombre maximum de lignes par MySQL (Billions) NDBCLUSTER?
- 21. Comment obtenir le nombre de lignes affectées dans sqlalchemy?
- 22. double [,] type, comment obtenir le nombre de lignes?
- 23. Insertion d'un nombre dynamique de lignes dans SQL Server
- 24. Renvoie le nombre de lignes affectées par les instructions UPDATE
- 25. Comment compter le nombre de lignes dans un jqGrid?
- 26. outil de reporting pour C++ qui indique le nombre de fois Exécuté donné une ligne
- 27. Comment obtenir le nombre de lignes dans JDBC?
- 28. Recherche du nombre maximum de lignes créées par heure?
- 29. Joindre deux colonnes avec le même nombre de lignes
- 30. Compte le nombre de lignes dans chaque groupe
et si vous utilisez un IDataReader vous pouvez simplement envelopper, il ne devrait jamais être vraiment nécessaire d'appeler son décompte, mais un hack qui peut fonctionner –
@ Sam, comment voulez-vous dire « envelopper "? J'ai un 'SqlDataReader', et la chose la plus proche d'un compte de lignes est la propriété' RecordsAffected' qui est toujours -1 dans ce cas ... – chezy525
Ceci est la méthode la plus sûre que celles listées ci-dessous (qui sont, , lisse!) - accéder à un champ privé pourrait se casser dans le futur sans avertissement (Microsoft pourrait changer l'implémentation d'une API publique sans casser l'API publique en changeant les noms de champs), mais la requête de compte fonctionnerait toujours. –