Estoy usando SQLBulkCopy para mover grandes cantidades de datos. Implementé el evento de notificación para notificarme cada vez que se ha procesado un cierto número de filas, pero el evento OnSqlRowsCopied no se activa cuando se completa el trabajo. ¿Cómo obtengo el número total de filas copiadas cuando se completa el writetoserver de SQLBulkCopy?SQLBulkCopy Recuento de filas cuando está completo
Respuesta
Creo que debe ejecutar una consulta COUNT() en la tabla después de terminar, como en el ejemplo here de MSDN.
Aparte de eso, ¿no puedes decirlo al frente? p.ej. si pasa una DataTable a WriteToServer(), entonces sabrá cuántos registros hace un .Rows.Count en él.
este truco (utilizando la reflexión) es una opción:
/// <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);
}
}
y luego usar la clase de la siguiente manera:
int rowsCopied = SqlBulkCopyHelper.GetRowsCopied(bulkCopyObjectInYourCode);
Espero que esto ayude.
¿Por qué no hacer que sea un método de extensión? public static int GetRowsCopied (este SqlBulkCopy bulkCopy) – mhenry1384
Mi única preocupación aquí es que obtiene un campo interno y no juega con la API pública. Ese campo interno podría cambiar en una implementación futura sin romper la API, y eso rompería este código. (Puede que sea poco probable, pero es posible, y he visto cosas así antes). Es muy peligroso tener acceso a campos privados por esta misma razón: podría funcionar hoy, pero no hay garantía de que funcione. mañana. (Realmente, hubiera sido bueno si Microsoft acabara de exponer una propiedad pública aquí). –
Para completar, he implementado como un método de extensión e incluí el espacio de nombres. Copia y pega esta clase si quieres una solución rápida para obtener el recuento copiado. Nota: Este recuento no tiene en cuenta la cantidad de filas realmente insertadas cuando Ignorar duplicados está activado.
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);
}
}
}
Mediante el uso de SqlBulkCopy.SqlRowsCopied Event
(se produce cada vez que el número de filas especificado por la propiedad NotifyAfter
ha sido procesado) podemos lograr SqlBulkCopy recuento de filas cuando se complete.
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;
}
Aquí es lo que hice - es una ligera modificación de la solución de Rahul Modi en este hilo (básicamente sólo se pone la línea evento SqlRowsCopied, que creo que es un poco más limpio en este caso que la creación del nuevo controlador de eventos método):
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. Recuento de filas OrientDB
- 2. Cómo detectar cuando innerHTML está completo
- 3. sqlbulkcopy - no permite DBNull.Value.?
- 4. MySQL filas de recuento de desempeño anteriores
- 5. Recuento de filas de Heroku Incorrecto
- 6. C# filas de recuento EPPlus OpenXML
- 7. SQL recuento de filas vs Top
- 8. Hibernate Criterios y recuento de filas restricción
- 9. Windows Azure Tables - Recuento de filas?
- 10. recuento total de filas en iReport
- 11. ¿Cómo funciona SqlBulkCopy?
- 12. Cómo obtener el recuento de filas de ObjectDataSource
- 13. ¿Mi programa está completo?
- 14. Pregunta de FMDB SQLite: recuento de filas de una consulta?
- 15. Cambiar el recuento de filas predeterminado de jquery datatables mostrado
- 16. ¿Cómo suprimir por completo las filas duplicadas
- 17. Recuento de filas de una familia de columnas en Cassandra
- 18. Recuento total de filas para paginación usando criterios JPA API
- 19. Cómo obtengo un recuento de filas de una UITableView
- 20. filas de recuento de hibernación con algunos criterios
- 21. Alcance de "Establecer recuento de filas" en SQL
- 22. SqlBulkCopy lento como melaza
- 23. NHibernate.StaleStateException: recuento de filas inesperado: 0; esperado: 1
- 24. Determine el recuento de filas del repetidor en asp.net
- 25. ¿Recuento de filas para una tabla en MySQL?
- 26. ¿Cómo obtengo el recuento de filas en JDBC?
- 27. SqlBulkCopy y Entity Framework
- 28. SQLBulkCopy o inserción masiva
- 29. SqlBulkCopy Not Working
- 30. Consulta SQL para eliminar filas más antiguas en un determinado recuento de filas?
y si está utilizando una IDataReader que sólo puede envolver, nunca debería ser realmente una necesidad de llamar a la cuenta, pero es un truco que puede trabajar –
@ Sam, ¿Qué quiere decir "envolverlo "¿?" Tengo un 'SqlDataReader', y lo más parecido a un recuento de filas que tiene es la propiedad' RecordsAffected' que siempre es -1 en este caso ... – chezy525
Este es el método más seguro que los que se enumeran a continuación (que son, sin duda, , slick!) - acceder a un campo privado podría romperse en el futuro sin previo aviso (Microsoft podría cambiar la implementación de una API pública sin romper la API pública al cambiar los nombres de los campos), pero la consulta de recuento aún funcionaría. –