¿Cómo usar Dapper para inserciones masivas con claves externas?

bulkinsert c# dapper sql-server

Pregunta

Tengo una estructura de datos C # así:

public class Invoice
{
    public string InvoiceNumber {get;set;}
    public List<SalesPerson> SalesPersons {get;set;}
}

public class SalesPerson
{
    public string Name {get;set;}
}

Esto corresponde a dos tablas: Factura y SalesPerson. Una factura puede tener cualquier cantidad de estas asociaciones.

Ahora, estoy creando un servicio de carga masiva, tomando un archivo CSV y creando un conjunto de facturas (cada una con cierta cantidad de registros SalesPerson asociados).

Puedo pensar en una forma ingenua de hacer esto con Dapper: recorrer cada Factura, insertarla, obtener una identidad (una columna de ID de enteros), recorrer cada SalesPerson en esa factura, insertar usando la identidad que obtuve como clave externa. Pero parece que va a ser mucho tráfico innecesario a / desde mi servidor SQL.

Soy consciente de la inserción 'masiva' donde puedo ejecutar un comando de inserción varias veces, pero no veo cómo funcionaría en este caso, ya que no conozco la clave externa en el momento en que estoy construyendo Los parametros.

¿Hay una mejor manera de hacer este inserto que la forma ingenua que he descrito anteriormente? ¿Dapper es la herramienta equivocada para esto? (Estoy usando SQL Server; si hay algunos comandos tSQL que pueden ayudarme, no los conozco)

Respuesta aceptada

Dapper pretende ser una herramienta ADO.NET de propósito general, con un mínimo de soporte para las características específicas del proveedor. La inserción masiva no es una API general , la clase de inserción masiva no es genérica. Si está utilizando SQL Server, SqlBulkCopy sería la opción obvia. Al combinar eso con un modelo de objetos basado en clases, FastMember es un buen aliado. Por ejemplo:

var data = ... // some List<Foo> where Foo has Id, Name and Description
using(var bcp = new SqlBulkCopy(connection)) // SqlBulkCopy
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) // FastMember
{
    // these bits are part of the SqlBulkCopy API; WriteToServer accepts *either* a
    // DataTable or an IDataReader; we're providing the latter via FastMember
    bcp.DestinationTableName = "SomeTable";
    bcp.WriteToServer(reader);
}

En términos de apuesto, no hay soporte para valores de tabla de parámetros, pero que requiere de usted para crear un tipo con nombre de SQL Server. Pero si desea considerar esa ruta, consulte ¿Da Dapper es compatible con los parámetros de valor de tabla de SQL 2008?

Una ventaja de la opción de parámetros de valores de tabla es que puede combinar su INSERT con la cláusula OUTPUT para recuperar todos los ID de una vez. En comparación: con SqlBulkCopy necesitaría consultar los datos después de la inserción (esencialmente: nada vuelve de una operación SqlBulkCopy ).



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é