Lograr que SqlBulkCopy respete los nombres de columna

c# sqlbulkcopy tsql

Pregunta

Estoy en el proceso de convertir algunas rutinas de informes basadas en procedimientos almacenados para ejecutar en C #. La idea general es utilizar todas las maravillas de C # / .NET Framework y luego enviar los resultados a la base de datos. Todo ha ido bien, excepto por un problema que encontré ayer y resolví hoy.

Para realizar la importación, estoy creando mediante programación un DataTable y utilizando SqlBulkCopy para mover los resultados al servidor.

p.ej

 DataTable detail = new DataTable();
 detail.Columns.Add(new DataColumn("Stock", Type.GetType("System.Decimal")));
 detail.Columns.Add(new DataColumn("Receipts", Type.GetType("System.Decimal")));
 detail.Columns.Add(new DataColumn("Orders", Type.GetType("System.Decimal")));

La tabla de importación tenía los campos en el siguiente orden.

...
Stock decimal(18,4),
Orders decimal(18,4),
Receipts decimal(18,4)
...

Esencialmente, el valor de Recibos fue en Órdenes, y viceversa.

Evidentemente, esto se debe a que SqlBulkCopy no parece estar cumpliendo con el nombre de la columna que le he dicho que rellene, solo va por la posición ordinal.

Este es un problema para mí ya que usamos la comparación de SQL de Redgate. Cuando se empujan los cambios de una base de datos a otra, la posición ordinal de las columnas no se mantiene necesariamente. (p. ej., si inserta una nueva columna como tercer campo ordinal, la Comparación de SQL simplemente la agregará a la tabla en una sincronización, lo que la convertirá en la última columna).

Esto ensucia seriamente con mi solución. Ahora, estas son solo tablas de 'importación', así que si es necesario, puedo eliminarlas y recrearlas como parte de cualquier script de migración con las posiciones ordinales intactas. Aunque prefiero no hacer eso.

¿Hay alguna forma de obligar a SqlBulkCopy a respetar los nombres de columna que le indica que complete?

Respuesta aceptada

De http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.columnmappings.aspx :

Sin embargo, si los recuentos de columnas difieren, o las posiciones ordinales no son consistentes, debe usar ColumnMappings para asegurarse de que los datos se copien en las columnas correctas.

Para obtener un código de muestra, consulte "Asignación de columnas" en http://www.sqlteam.com/article/use-sqlbulkcopy-to-quickly-load-data-from-your-client-to-sql-server


Respuesta popular

Aquí hay una solución para solucionar este 'error'.

El valor predeterminado es mapear por ordinal / posición.

En mi caso, estaba cargando desde una hoja de cálculo con columnas en orden aleatorio. Aquí hay una solución rápida (la tabla es mi DataTable que está 'fuera de orden ordinal', y bulkCopy es el objeto SqLBulkCopy)

foreach (DataColumn col in table.Columns)
{
    bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}

Como puede ver, solo lo estoy obligando a reordenar por nombre, a pesar de que los nombres son IDÉNTICOS.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué