una type pasar parse lista how ejemplo convert c# sql sql-server ado.net bulkinsert

c# - type - SqlBulkCopy de una lista<>



pasar una lista a un datatable c# (4)

¿Cómo puedo hacer una gran inserción con SqlBulkCopy de una lista <> de objeto simple?

¿Implemento mi IDataReader personalizado?


Con FastMember , puedes hacer esto sin tener que pasar por DataTable (que, en mis pruebas, más que duplica el rendimiento):

using(var bcp = new SqlBulkCopy(connection)) using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) { bcp.DestinationTableName = "SomeTable"; bcp.WriteToServer(reader); }

Tenga en cuenta que ObjectReader también puede trabajar con fuentes no genéricas, y no es necesario especificar los nombres de los miembros por adelantado (aunque probablemente desee utilizar el aspecto SqlBulkCopy de SqlBulkCopy si no los especifica en el propio ObjectReader ).


Dependiendo de lo que esté tratando de lograr al llamar a SqlBulkCopy en primer lugar, podría tener más sentido utilizar un parámetro de valor de tabla (TVP). El uso de un TVP haría que sea trivial enviar una colección de cualquier tipo personalizado. Los datos pueden transmitirse para que pueda evitar el DataTable (como en la respuesta de @Marc Gravell) y también puede evitar SqlBulkCopy . Los TVP permiten una total flexibilidad de cómo manejar los datos una vez que llegan a SQL Server cuando llama a un Procedimiento almacenado para pasar los datos de TVP y aparece como una Variable de tabla con la que puede hacer cualquier cosa, no solo INSERT (que es el caso con SqlBulkCopy ). También puede recuperar datos a través de un SqlDataReader , datos como los valores de IDENTITY recién creados. Agregué un ejemplo y algunas notas adicionales sobre esta respuesta: ¿Cómo puedo insertar 10 millones de registros en el menor tiempo posible? . Y hace varios años escribí un artículo en SQL Server Central (se requiere registro gratuito), Streaming Data Into SQL Server 2008 desde una aplicación , que también se menciona en esa respuesta vinculada, proporcionando un ejemplo práctico de pasar una lista genérica de una costumbre. tipo, transmitido desde un archivo de texto de 3 millones de filas.


Simplemente cree un DataTable de su lista de objetos y llame a SqlBulkCopy.WriteToServer , pasando la tabla de datos.

Puede encontrar lo siguiente útil:

Para obtener el máximo rendimiento con SqlBulkCopy, debe establecer un BatchSize apropiado. 10,000 parece funcionar bien, pero el perfil para sus datos.

También puede observar mejores resultados al usar SqlBulkCopyOptions.TableLock .

Un análisis interesante e informativo del rendimiento de SqlBulkCopy se puede encontrar here .


Tarde en la fiesta, pero si agrega esta clase EntityDataReader de Microsoft, hay un método de extensión AsDataReader() que hace exactamente eso: github.com/matthewschrager/Repository/blob/master/…

(Ejemplo [List].AsDataReader() implementación :)

var connStr = ""; using (var connection = new SqlConnection(connStr)) { var startTime = DateTime.Now; connection.Open(); var transaction = connection.BeginTransaction(); try { //var connStr = connection.ConnectionString; using (var sbCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, transaction)) { sbCopy.BulkCopyTimeout = 0; sbCopy.BatchSize = 10000; sbCopy.DestinationTableName = "Foobars"; var reader = Foobars.AsDataReader(); sbCopy.WriteToServer(reader); } transaction.Commit(); } catch (Exception ex) { Console.WriteLine(ex.Message); transaction.Rollback(); } finally { transaction.Dispose(); connection.Close(); var endTime = DateTime.Now; Console.WriteLine("Upload time elapsed: {0} seconds", (endTime - startTime).TotalSeconds); } }