web-dev-qa-db-fra.com

Insérer une liste en utilisant dapper.NET C #

J'aimerais insérer une liste d'objets dans une table SQL.

Je connais cette question ici mais je ne comprends pas.

Voici ma classe:

public class MyObject 
{
    public int? ID { get; set; }
    public string ObjectType { get; set; }
    public string Content { get; set; }
    public string PreviewContent { get; set; }

    public static void SaveList(List<MyObject> lst)
    {
        using (DBConnection connection = new DBConnection())
        {
            if (connection.Connection.State != ConnectionState.Open)
                connection.Connection.Open();

            connection.Connection.Execute("INSERT INTO [MyObject] VALUE()",lst);                
        }
    }
}

J'aimerais savoir comment insérer ma liste à l'aide de Dapper, je ne veux pas faire une itération sur la liste et la sauvegarder un par un, j'aimerais les insérer tous dans une requête.

4

Vous pouvez les insérer comme vous le feriez pour INSERER une seule ligne:

public class MyObject 
{
    public int? ID { get; set; }
    public string ObjectType { get; set; }
    public string Content { get; set; }
    public string PreviewContent { get; set; }

    public static void SaveList(List<MyObject> lst)
    {
        using (DBConnection connection = new DBConnection())
        {
            if (connection.Connection.State != ConnectionState.Open)
                connection.Connection.Open();

            connection.Connection.Execute("INSERT INTO [MyObject] (Id, ObjectType, Content, PreviewContent) VALUES(@Id, @ObjectType, @Content, @PreviewContent)", lst);                
        }
    }
}

Dapper recherchera les membres de la classe nommés d'après vos paramètres SQL (@Id, @ObjectType, @Content, @PreviewContent) et les liera en conséquence.

10

Vous devez passer un paramètre table-value.
1. Créez un type de table dans votre base de données SQL.
2. Créez des paramètres dynamiques et ajoutez-y le datatable (nouvelles valeurs).
3. Exécuter.

SQL:

CREATE TYPE [dbo].[tvMyObjects] AS TABLE(
    [ID] INT,
    [ObjectType] [varchar](70), /*Length on your table*/
    [Content] [varchar](70), /*Length on your table*/
    [PreviewContent] [varchar](70) /*Length on your table*/
)

C #:

var dynamicParameters = new DynamicParameters();
dynamicParameters.Add("@MyObjects", lst
    .AsTableValuedParameter("dbo.tvMyObjects", new[] 
    {
        "ID" ,
        "ObjectType",
        "Content", 
        "PreviewContent"
    }));

connection.Connection.Execute(@"
    INSERT INTO [MyObject] (Id, ObjectType, Content, PreviewContent) 
    SELECT Id,
           ObjectType,
           Content,
           PreviewContent
    FROM   @MyObjects", dynamicParameters);

Plus d'infos: https://www.codeproject.com/Articles/835519/Passing-Table-Valued-Parameters-with-Dapper

1
Daniel Tshuva

Vous voudriez simplement changer votre code SQL en une instruction d'insertion valide dont les paramètres correspondent aux noms des propriétés de votre classe.

INSERT INTO MyObject VALUES(@Id, @ObjectType, @Content, @PreviewContent)

Ou si vous devez spécifier les colonnes de la table (par exemple, celles-ci ne sont pas toutes les colonnes de la table):

INSERT INTO MyObject (Id, ObjectType, Content, PreviewContent)
VALUES(@Id, @ObjectType, @Content, @PreviewContent)
0
Charles Mager

Vous pouvez utiliser les extensions Dapper.Contrib pour simplifier le code. J'ai trouvé que cela fonctionne bien pour quelques centaines d'enregistrements, mais pour les très gros encarts, je passe à SqlBulkCopy. La version synchrone est Insert au lieu de InsertAsync (comme vous pouvez le deviner). Assurez-vous que vos entités sont nommées comme le prévoit Dapper et possèdent une clé primaire, un ID ou ajoutez des annotations pour le nom de la table et la clé de votre entité.

using using Dapper.Contrib.Extensions; //Git

public async Task SaveChangesAsync(IList<MyEntity> myEntityValues)
{
     var conn = new SqlConnection(myconnectionString);
     if(conn.State != ConnectionState.Open)
         conn.Open();
     await conn.InsertAsync(myEntityValues);
     if (conn.State != ConnectionState.Closed)
     {
        conn.Close();
        conn.Dispose();
      }
}
0
Ron