So fügen Sie mit Dapper.NET eine C # -Liste in die Datenbank ein

75

Verwenden von , wie kann ich eine C# Listin Datenbank einfügen . Bisher ohne Dapper habe ich den folgenden Code verwendet, um die Listenwerte in die Datenbank einzufügen .

try
{                
    connection.Open();

    for (int i = 0; i < processList.Count; i++)
    {
        string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@Id, @st_Time, @ed_Time, @td_Time)";
        command = new SqlCommand(processQuery, connection);
        command.Parameters.Add("Id", SqlDbType.Int).Value = processList[i].ID;
        command.Parameters.Add("st_Time", SqlDbType.DateTime).Value = processList[i].ST_TIME;
        command.Parameters.Add("ed_Time", SqlDbType.DateTime).Value = processList[i].ED_TIME;
        command.Parameters.Add("td_Time", SqlDbType.DateTime2).Value = processList[i].TD_TIME;
        dataReader.Close();
        dataReader = command.ExecuteReader();
    }

    connection.Close();
}
catch (SqlException ex)
{
    //--Handle Exception
}

Ich bin mit dem Abrufen der Daten mit dapper vertraut, aber dies ist mein erster Versuch mit der Einfügeabfrage .

Ich habe den folgenden Code ausprobiert, indem ich einen ExceuteLink zur Abfrage verwendet habe, mich aber an die Schleife gehalten habe. Ich denke, mit dem Dapper-Tool ist keine Schleifenanweisung erforderlich.

connection.Execute(processQuery ... );

BEARBEITEN:

class ProcessLog
    {
        public int ID { get; set; }
        public DateTime ST_TIME { get; set; }
        public DateTime ED_TIME { get; set; }
        public DateTime TD_TIME { get; set; }
        public string frequency { get; set; }
    }

Bitte beraten Sie dazu. Zu Ihrer Information: Ich benutze SQL Server 2008.

Praveen
quelle

Antworten:

132

Du müsstest es ein bisschen anders machen. In Dapper stimmt es mit den AKA-Eigenschafts- oder Feldnamen überein, die mit den SQL-Parametern identisch sind. Angenommen, Sie hatten eine MyObject:

public class MyObject
{
    public int A { get; set; }

    public string B { get; set; }
}

Und vorausgesetzt processList = List<MyObject>, Sie möchten dies tun

foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, item);
}

Beachten Sie, dass die MyObjectEigenschaftsnamen A und B mit den SQL-Parameternamen @A und @B übereinstimmen.

Wenn Sie Objekte nicht umbenennen möchten, können Sie anstelle konkreter Typen anonyme Typen für die Zuordnungen verwenden:

foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, new { A = item.A, B = item.B });
}

BEARBEITEN:

Laut Marc Gravells Kommentar können Sie Dapper auch die Schleife für Sie machen lassen:

string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
connection.Execute(processQuery, processList);
Haney
quelle
137
Eigentlich wenig bekannte Tatsache: Dapper wird für Sie iterieren ; Die mittlere kann sein:connection.Execute("INSERT INTO PROCESS_LOGS VALUES (@A, @B)", processList);
Marc Gravell
1
@ DavidH Ich dachte, es werden keine Schleifen benötigt?
Praveen
4
Mein Gott, Marc, du hörst nie auf, mich zu überraschen. Jetzt muss ich den gesamten Code, den ich in den letzten 10 Tagen geschrieben habe, erneut überprüfen. (Da ich beschlossen habe, dieses kleine Juwel zu probieren)
Steve
5
Gibt es eine Möglichkeit, (@a1, @b1),(@a2, @b2)mit Dapper zu simulieren ? Ich versuche SQL Server zu verwenden MERGE tble USING VALUES (('a1', 'b1'),('a2','b2')) AS foo(a,b) ON tble.a=foo.a WHEN MATCHED.... Wenn nicht, würde ich lieber viele Anweisungen iterieren und ausführen, als eine temporäre Tabelle zu verwenden, aber Dapper, der meine Liste in Klammern erstellt, wäre sehr nett. Bin zweifelhaft, da ich denke, dass es herstellerspezifisch ist. Obwohl MySQL durch Kommas getrennte Klammern verwendet, um mehrere Zeilen einzufügen, ist dies möglicherweise nicht der Fall? ( INS INTO tbl (a,b) VALUES (a1,b1),(a2,b2)).
Chris
2
@ Mackan Dapper wird nicht, aber LINQ: listOfChildren.Select(childId => new { A = parentId, B = childId})als
Argument verwenden
23

Ich glaube, die Masseneinfügung ist besser, als die Liste zu iterieren und einzeln einzufügen.

SqlTransaction trans = connection.BeginTransaction();

connection.Execute(@"
insert PROCESS_LOGS(Id, st_Time, ed_Time, td_Time)
values(@Id, @st_Time, @ed_Time, @td_Time)", processList, transaction: trans);

trans.Commit();

Referenz: https://stackoverflow.com/a/12609410/1136277

Thalles Noce
quelle
2
Ich glaube nicht, dass das ein Masseneinsatz ist. Einzelne Einfügungen werden durchgeführt. Siehe die Kommentare in dem von Ihnen angegebenen Link.
Bob Horn