¿La característica "ejecutar comando varias veces" da como resultado múltiples viajes de ida y vuelta a la base de datos?

dapper

Pregunta

En la documentación de Dapper , dice que puede usar un parámetro IEnumerable para ejecutar un comando varias veces. Da el siguiente ejemplo:

connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"

¿Esto resultará en múltiples viajes de ida y vuelta a la base de datos (es decir, uno para cada T en IEnumerable<T> )? ¿O es Dapper lo suficientemente inteligente como para transformar las múltiples consultas en un lote y simplemente hacer un viaje de ida y vuelta? La documentación dice que un ejemplo de uso es la carga por lotes, así que sospecho que solo hace un viaje de ida y vuelta, pero quiero estar seguro antes de usarlo para el código sensible al rendimiento.

Como una pregunta de seguimiento, y dependiendo de la respuesta a la primera, me gustaría saber cómo se manejan las transacciones. Es decir, ¿hay una transacción para todo el conjunto de T s, o una transacción por T ?

Respuesta aceptada

Finalmente llegué a mirar esto de nuevo. Al mirar el código fuente (en \Dapper\SqlMapper.cs ), encontré el siguiente fragmento en el método ExecuteImpl :

// ...
foreach (var obj in multiExec)
{
    if (isFirst)
    {
        masterSql = cmd.CommandText;
        isFirst = false;
        identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
        info = GetCacheInfo(identity, obj, command.AddToCache);
    }
    else
    {
        cmd.CommandText = masterSql; // because we do magic replaces on "in" etc
        cmd.Parameters.Clear(); // current code is Add-tastic
    }
    info.ParamReader(cmd, obj);
    total += cmd.ExecuteNonQuery();
}
// ...

La parte interesante está en la penúltima línea donde se llama ExecuteNonQuery . Se invoca ese método en cada iteración del bucle for , así que supongo que no se está procesando en el sentido de una operación basada en conjuntos. Por lo tanto, se requieren múltiples viajes de ida y vuelta. Sin embargo, se está agrupando en el sentido de que todas las operaciones se realizan en la misma conexión, y dentro de la misma transacción, si así se especifica.

La única forma en que se me ocurre hacer una operación basada en conjuntos es crear un tipo de valor de tabla personalizado (en la base de datos) para el objeto de interés. Luego, en el código .NET pase un objeto DataTable que contenga nombres y tipos coincidentes como un parámetro de comando. Si hubiera una manera de hacerlo sin tener que crear un tipo de tabla para cada objeto, me encantaría saberlo.



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é