Dapper multi insert retournant les objets insérés

dapper sql sql-insert

Question

À l'aide de Dapper, j'aimerais implémenter une méthode prenant un IEnumberable d'objets de type User . Maintenant, l' User se présente comme suit:

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; }
}

Le point ici est que UserId , DateCreated et DateChanged ne doivent jamais être définis via object, d'où le mot-clé internal . Au lieu de cela, la base de données renseignera ces valeurs.

Étant donné que les objets sont donc modifiés dans le cadre de l'opération d'insertion, je souhaite renvoyer un autre IEnumerable d'objets de type User mais cette fois avec les propriétés correspondantes renseignées.

Récemment, j'ai réalisé que je pouvais laisser Dapper parcourir en boucle les objets User dans IEnumerable comme suit:

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

C'est bien parce que je n'ai pas à écrire moi-même le foreach . Le problème ici est que Execute ne renverra que le nombre de lignes réellement insérées.

Alors je l'ai essayé en utilisant Query comme suit:

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);
}

Cependant, cela lève simplement une exception InvalidOperationException avec le message "Une séquence énumérable de paramètres (tableaux, listes, etc.) n'est pas autorisée dans ce contexte".

Je suis coincé avec ça. Comment puis-je faire ce travail?

Dois-je parcourir en boucle mon entrée IEnumerable exécutant la Query pour chaque objet à l'intérieur du corps de la boucle? IDbTransaction paramètre IDbTransaction de la méthode Query serait inutile si je souhaitais insérer tous User objets User dans la même transaction, de sorte que je devrais envelopper la boucle entière dans une transaction au lieu de la transmettre à Query .

Quelle est la "bonne" façon d'insérer plusieurs objets à l'aide de Dapper et de renvoyer les objets entièrement remplis à l'appelant?

Réponse acceptée

insérer ou mettre à jour la liste d'objets avec Dapper.Net vous ne pouvez pas utiliser la requête

 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();
   ...
} 

vous devez utiliser uniquement Execute for multi insert ou update

Execute("your_query",your_list, your_transaction);

donc si vous avez besoin d'insérer et de retourner des identifiants pour les enregistrements insérés

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

// Exemple d'insertion multiple et de retour de l'enregistrement complet

  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. *] Retournera la ligne d'insertion complète avec id et vous êtes libre de retourner n'importe quelle propriété en remplaçant l'astérisque par propertyname [OUTPUT INSERTED.Id] ne retournera que l'identifiant

// sera bon pour une petite liste

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

// pour Big List, vous pouvez utiliser SqlBulkCopy pour lire ce lien ici



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi