Intentando que UPSERT trabaje en un conjunto de datos usando dapper

c# dapper sql-server upsert

Pregunta

Estoy tratando de trabajar en una colección de ID (no la clave principal, es decir, una columna int de identidad) en una tabla usando dapper. No es necesario que sea una función inteligente, solo se incluye en caso de que eso ayude.

Me pregunto si es posible (ya sea mediante SQL directo o usando una función dapper) ejecutar un upsert en una colección de ID (específicamente un IEnumerable de IEnumerable ).

Realmente solo necesito un ejemplo simple para comenzar, así que un ejemplo sería:


Tengo tres objetos de tipo Foo:

  1. {"ExternalID": 1010101, "DescriptorString": "Soy una cadena descriptiva", "OtherStuff": "Esta es otra cosa"}
  2. {"ExternalID": 1010122, "DescriptorString": "Soy un string descriptivo123", "OtherStuff": "Esta es otra cosa123"}
  3. {"ExternalID": 1033333, "DescriptorString": "Soy un string descriptivo555", "OtherStuff": "Esta es otra cosa555"}

Tengo una tabla llamada Bar, con esos mismos nombres de columna (donde solo existe 1033333):

Table Foo
ID de columna | ExternalID | DescriptorString | Otras cosas
Valor [1] | [1033333] | ["Soy una cadena descriptiva555"] | ["Esta es otra cosa555"]


Respuesta popular

Bueno, ya que dijiste que esto no necesitaba ser basado en el dapper ;-), diré que la forma más rápida y limpia de obtener estos datos es usar Parámetros con valores de tabla (TVP) que se introdujeron en SQL Server. 2008. Debe crear un tipo de tabla definido por el usuario (una vez) para definir la estructura, y luego puede usarla en consultas ad hoc o pasar a un procedimiento almacenado. Pero de esta forma no necesita exportar a un archivo solo para importar, ni necesita convertirlo a XML solo para convertirlo a una tabla.

En lugar de copiar / pegar un bloque de código grande, he observado tres enlaces a continuación donde he publicado el código para hacerlo (todos aquí en SO). Los primeros dos enlaces son el código completo (SQL y C #) para lograr esto (el segundo enlace es el más análogo a lo que intenta hacer). Cada una de ellas es una pequeña variación del tema (que muestra la flexibilidad de usar TVP). El tercero es otra variación, pero no el código completo, ya que solo muestra las diferencias de uno de los dos primeros para adaptarse a esa situación particular. Pero en los 3 casos, los datos se transmiten desde la aplicación a SQL Server . No hay creación de ninguna colección adicional o archivo externo; utiliza lo que tiene actualmente y solo necesita duplicar los valores de una sola fila a la vez para enviarlos. Y en el lado de SQL Server, todo viene como una variable de tabla poblada. Esto es mucho más eficiente que tomar datos que ya tiene en la memoria, convertirlos en un archivo (toma tiempo y espacio en el disco) o XML (toma CPU y memoria) o una DataTable (para SqlBulkCopy , toma CPU y memoria) u otra cosa, solo para confiar en un factor externo como el sistema de archivos (los archivos deberán ser limpiados, ¿no?) o para analizar XML.

Ahora, hay algunos problemas con el comando MERGE (consulte Usar precaución con la instrucción MERGE de SQL Server ) que podría ser una razón para evitar su uso. Por lo tanto, he publicado el código "upsert" que he estado utilizando durante años a una respuesta en DBA.StackExchange:



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é