3 registros con la misma ID pero cambian columnas diferentes usando SqlBulkCopy

bulkinsert c# primary-key sqlbulkcopy

Pregunta

Estoy haciendo una conversión con SqlBulkCopy. Actualmente tengo una colección de clases de IList que básicamente puedo hacer una conversión a un DataTable para usar con SqlBulkCopy.

El problema es que puedo tener 3 registros con la misma ID.

Déjame explicarte .. aquí hay 3 registros

ID      Name         Address
1       Scott        London
1       Mark         London
1                    Manchester

Básicamente, necesito insertarlos secuencialmente ... por lo tanto, inserto el registro 1 si no existe, luego el siguiente registro, si existe, necesito actualizar el registro en lugar de insertar un nuevo 1 (note que el ID sigue siendo 1). En el caso del segundo registro, reemplacé ambas columnas, nombre y dirección en la identificación 1.

Finalmente, en el tercer registro, notará que el nombre no existe, pero su ID 1 y tiene una dirección de Manchester, por lo que necesito actualizar el registro pero NO CAMBIAR el nombre, sino actualizar Manchester ... por lo tanto, el tercer registro haría que el id1 =

ID      Name      Address
1       Mark      Manchester

¿Alguna idea de cómo puedo hacer esto? Estoy en una pérdida.

Gracias.

EDITAR

Ok una pequeña actualización. Administraré y fusionaré mis registros antes de usar SQLbulkCopy. ¿Es posible obtener una lista de lo que tuvo éxito y lo que falló ... o es un caso de TODOS o nada? Supongo que no hay otra alternativa a SQLbulkCopy que hacer actualizaciones?

sería ideal poder insertar todo y los que fallaron se insertan en una tabla temporal ... por lo tanto, solo debo preocuparme por corregir los que están en mi tabla fallida, ya que los demás que conozco están todos bien

Respuesta aceptada

Ya que necesita procesar esos datos en un DataTable todos modos (a menos que esté escribiendo un IDataReader personalizado), debe combinar los registros antes de entregarlos a SqlBulkCopy ; por ejemplo (en pseudo código):

/* create empty data-table */
foreach(row in list) {
    var row = /* try to get exsiting row from data-table based on id */
    if(row == null) { row = /* create and append row to data-table */ }
    else { merge non-trivial properties into existing row */
}

luego pase el DataTable a SqlBulkCopy una vez que tenga los datos deseados.


Re la edición; en ese escenario, subiría a una tabla de preparación (solo una tabla normal que tiene un esquema como los datos cargados, pero generalmente no contiene claves externas, etc.) y luego utilizaría TSQL normal para mover los datos a las tablas transaccionales. Además de la compatibilidad total con TSQL, esto también permite un mejor registro de las operaciones. En particular, quizás mire la cláusula OUTPUT de INSERT que puede ayudar a operaciones masivas complejas.


Respuesta popular

No puede hacer actualizaciones con copia masiva (inserción masiva), solo inserte. De ahí el nombre.

Debe corregir los datos antes de insertarlos. Si esto significa que tiene actualizaciones de las filas preexistentes, no puede insertarlas ya que generará el conflicto clave.

Puede realizar una inserción masiva en una tabla temporal y ejecutar las instrucciones de inserción o actualización apropiadas, solo inserte las nuevas filas y emita las instrucciones de actualización para el resto, o elimine las filas preexistentes después de obtenerlas y corregir los datos antes de reinsertarlos.

Pero no hay manera de persuadir a la copia masiva para actualizar una fila existente.



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é