Dapper multi insert devolviendo objetos insertados

dapper sql sql-insert

Pregunta

Usando Dapper, me gustaría implementar un método que tome un IEnumberable de objetos de tipo User . Ahora, el User ve como sigue:

public class User
{
  public int UserId { get; internal set; }
  public DateTime DateCreated { get; internal set; }
  public DateTime DateChanged { get; internal set; }
  public string Username { get; set; }
}

El punto aquí es que UserId , DateCreated y DateChanged nunca se establecerán a través del objeto, de ahí la palabra clave internal . En su lugar, la base de datos llenará estos valores.

Debido a que los objetos se modifican como parte de la operación de inserción, deseo devolver otro IEnumerable de objetos de tipo User pero esta vez con las propiedades correspondientes completadas.

Recientemente me di cuenta de que puedo dejar que Dapper IEnumerable los objetos de User en IEnumerable siguiente manera:

public int Insert(IEnumerable<User> users)
{
  string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username)");
  return GetOpenConnection().Execute<User>(sql, users);
}

Esto es bueno porque no tengo que escribir el foreach yo mismo. Ahora, el problema aquí es que Execute solo devolverá el número de filas realmente insertadas.

Así que lo probé usando Query como sigue:

public IEnumerable<User> Insert(IEnumerable<User> users)
{
  string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username) SELECT * FROM [User] WHERE UserId = scope_identity()");
  return GetOpenConnection().Query<User>(sql, users);
}

Sin embargo, esto simplemente lanza una excepción InvalidOperationException con el mensaje "No se permite una secuencia enumerable de parámetros (matrices, listas, etc.) en este contexto".

Estoy atascado con esto. ¿Cómo puedo hacer este trabajo?

¿Tengo que realizar un bucle a través de mi entrada IEnumerable ejecutando la Query para cada objeto dentro del cuerpo del bucle? De esta manera, el parámetro IDbTransaction del método Query sería inútil si quisiera insertar todos los objetos de User en la misma transacción, así que tendría que envolver todo el bucle en una transacción en lugar de pasar la transacción a Query .

¿Cuál es la manera "correcta" de insertar múltiples objetos usando Dapper y devolver los objetos completamente poblados al llamante?

Respuesta aceptada

para insertar o actualizar la Lista de objetos con Dapper.Net no puede usar Query

 connection.Query<Object>("your_query",your_list) 
 //connection.Query<Object>: use to select IEnumrable<object> from db
 //connection.QueryMultiple: use to execut multiple query at once then read result one by one 

var sql = 
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";

using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
  var customer = multi.Read<Customer>().Single();
  var orders = multi.Read<Order>().ToList();
  var returns = multi.Read<Return>().ToList();
   ...
} 

debe usar solo Ejecutar para inserción múltiple o actualización

Execute("your_query",your_list, your_transaction);

por lo tanto, si necesita insertar múltiples identificaciones y devolverlas para registros insertados

// **using transaction depend on your needs**

// Ejemplo para inserción múltiple y devolución de registro completo

  string query = @"Insert Into _TableName ( _columns) 
                                  OUTPUT INSERTED.* 
                                values ( _parameters )"; //parameters should be same as object properties name to let dapper do correct mapping 

[OUTPUT INSERTED. *] Devolverá la fila de inserción completa con id y podrá devolver cualquier propiedad reemplazando asterisco con propertyname [OUTPUT INSERTED.Id] devolverá solo id.

// será bueno para la lista pequeña

 for (int i = 0; i < youList.Count-1; i++)
                {
                    youList[i] = DbConnection.Query<object>(query, youList[i]).FirstOrDefault();
                } // for loop is better for preformance

// para la lista grande puede usar SqlBulkCopy revise este enlace aquí



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é