C# – Ausführen grundlegender SQL-Abfragen mit Dapper

C# – Ausführen grundlegender SQL-Abfragen mit Dapper

Hier ist ein Beispiel für die Verwendung von Dapper zur Ausführung einer einfachen SELECT-Abfrage:

using System.Data.SqlClient;
using Dapper;

public IEnumerable<Movie> GetAllMovies()
{
	using (var con = new SqlConnection(connectionString))
	{
		return con.Query<Movie>("SELECT * FROM Movies");
	}
}
Code language: C# (cs)

Dapper abstrahiert den sich wiederholenden Code, der mit der Ausführung von SQL-Abfragen verbunden ist, einschließlich Mapping-Parametern und Abfrageergebnissen. Es tut dies ohne jegliche Konfiguration (es mappt durch Reflektion).

In diesem Artikel zeige ich weitere Beispiele für die Verwendung von Dapper in gängigen Szenarien, z. B. das Hinzufügen von Abfrageparametern und das Einfügen von Datensätzen.

Hinweis:Falls noch nicht geschehen, fügen Sie das Dapper-Nuget-Paket hinzu .

Suchparameter hinzufügen

Um Abfrageparameter mit Dapper hinzuzufügen, übergeben Sie ein Objekt für param Argument:

public IEnumerable<Movie> GetMoviesForYear(int year)
{
	using (var con = new SqlConnection(connectionString))
	{
		return con.Query<Movie>("SELECT * FROM Movies WHERE YearOfRelease=@year", 
			param: new { year });
	}
}
Code language: C# (cs)

Sie können jedes Objekt übergeben, einschließlich anonymer Typen (wie oben gezeigt). Dapper versucht, die Eigenschaften aus param abzubilden Objekt zu den Parameterplatzhaltern (z. B. „@year“) in der Abfrage.

Aufruf einer gespeicherten Prozedur

Angenommen, Sie möchten die folgende gespeicherte Prozedur aufrufen:

CREATE PROCEDURE spGetMoviesForYear
	@year int
AS
BEGIN
	SELECT * FROM Movies WHERE YearOfRelease=@year
END
Code language: plaintext (plaintext)

Hier ist ein Beispiel dafür, wie diese gespeicherte Prozedur mit Dapper aufgerufen wird:

public IEnumerable<Movie> GetMoviesForYearSP(int year)
{
	using (var con = new SqlConnection(connectionString))
	{
		return con.Query<Movie>("dbo.spGetMoviesForYear", 
			param: new { year }, 
			commandType: System.Data.CommandType.StoredProcedure);
	}
}
Code language: C# (cs)

Sie geben den gespeicherten Prozessnamen und alle Parameter an und setzen das commandType-Argument auf CommandType.StoredProcedure.

Datensätze einfügen

Hier ist ein Beispiel für das Einfügen eines einzelnen Filmdatensatzes:

private const string INSERT_SQL =
@"INSERT INTO [Movies]
	([Name]
	,[YearOfRelease]
	,[Description]
	,[Director]
	,[BoxOfficeRevenue])	   
VALUES
	(@Name,
	@YearOfRelease,
	@Description,
	@Director,
	@BoxOfficeRevenue)";

public void Insert(Movie movie)
{
	using (var con = new SqlConnection(connectionString))
	{
		con.Execute(INSERT_SQL, param: movie);
	}
}
Code language: C# (cs)

Einfügungen sind etwas mühsam zu programmieren, da die INSERT-Anweisung im Vergleich zu anderen SQL-Anweisungen so ausführlich ist. Es gibt Erweiterungsbibliotheken für Dapper, die die CRUD-Operationen abstrahieren, sodass Sie kein SQL schreiben müssen, aber ich persönlich verwende diese nicht. Einer der Vorteile von Dapper ist, dass es die von Ihnen geschriebene SQL-Abfrage ausführt, sodass es keine Überraschungen gibt.

In der Lage sein, das Filmobjekt für den param zu übergeben Argument hilft, da Sie die Parameterliste nicht eingeben müssen. Zum Schreiben der INSERT-Anweisung verwende ich normalerweise Script Table as> INSERT INTO in SSMS, um ein Startpunktskript zu erstellen, oder generieren Sie die Abfragen mithilfe von Metadaten.

Erhalten des eingefügten Identitätswerts

Wenn Sie einen Datensatz in eine Tabelle mit einer Identitätsspalte einfügen, können Sie den eingefügten Identitätswert abrufen, indem Sie der Abfrage OUTPUT INSERTED.Id hinzufügen. Verwenden Sie ExecuteScalar(), um den einzelnen zurückgegebenen Wert zu erhalten:

private const string INSERT_OUTPUT_ID_SQL =
@"INSERT INTO [Movies]
	([Name]
	,[YearOfRelease]
	,[Description]
	,[Director]
	,[BoxOfficeRevenue])
OUTPUT INSERTED.Id
VALUES
	(@Name,
	@YearOfRelease,
	@Description,
	@Director,
	@BoxOfficeRevenue)";
	
public int InsertAndReturnId(Movie movie)
{
	using (var con = new SqlConnection(connectionString))
	{
		return con.ExecuteScalar<int>(INSERT_OUTPUT_ID_SQL, param: movie);
	}
}
Code language: C# (cs)

Einfügen mehrerer Datensätze

Wenn Sie eine Liste von Objekten für param übergeben -Argument führt Dapper die SQL-Abfrage für jedes Objekt in der Liste aus:

private const string INSERT_SQL =
@"INSERT INTO [dbo].[Movies]
	([Name]
	,[YearOfRelease]
	,[Description]
	,[Director]
	,[BoxOfficeRevenue])	   
VALUES
	(@Name,
	@YearOfRelease,
	@Description,
	@Director,
	@BoxOfficeRevenue)";

public void InsertMultiple(List<Movie> movies)
{
	using (var con = new SqlConnection(connectionString))
	{
		con.Execute(INSERT_SQL, param: movies);
	}
}
Code language: C# (cs)

Das Ausführen vieler INSERT-Anweisungen nacheinander kann die Leistung wirklich beeinträchtigen. Stellen Sie sicher, dass Sie Ihren Code auf Leistung testen, wenn Sie erwarten, dass viele Daten wie diese häufig eingefügt werden. Ich empfehle dringend, einen BULK INSERT durchzuführen, wenn Sie auf Leistungsprobleme stoßen.

Aktualisierung von Aufzeichnungen

Hier ist ein Beispiel dafür, wie Sie einen Datensatz mit Dapper aktualisieren:

public void UpdateYear(Movie movie)
{
	using (var con = new SqlConnection(connectionString))
	{
		con.Execute("UPDATE Movies SET YearOfRelease=@year WHERE Id=@id", 
			param: new {year = movie.YearOfRelease, id = movie.Id });
	}
}
Code language: C# (cs)

Sie können die UPDATE-Anweisung so einfach wie möglich halten, indem Sie nur das absolute Minimum an Spalten in die Abfrage aufnehmen. Wenn eine Spalte nicht in der Aktualisierungsliste oder in der Where-Klausel enthalten sein muss, lassen Sie sie weg.

Aktualisieren mehrerer Datensätze

Wenn Sie mehrere Datensätze mit unterschiedlichen Werten aktualisieren, müssen Sie mehrere UPDATE-Anweisungen ausführen. Angenommen, Sie möchten Folgendes festlegen:

  • Film A YearOfRelease=2021
  • Film B Jahr der Veröffentlichung=2022

Um dies mit Dapper zu tun, können Sie eine Liste für den param übergeben Streit. Es wird die UPDATE-Anweisung für jedes Filmobjekt in der Liste ausführen:

public void UpdateMultipleToDifferentYears(List<Movie> movies)
{
	using (var con = new SqlConnection(connectionString))
	{
		con.Execute("UPDATE Movies SET YearOfRelease=@YearOfRelease WHERE Id=@Id",
			param: movies);
	}
}
Code language: C# (cs)

Wenn Sie mehrere Datensätze mit demselben Wert aktualisieren, können Sie eine einzelne UPDATE-Anweisung mit einer WHERE IN-Klausel ausführen. Angenommen, Sie möchten mehrere Filme so aktualisieren, dass sie YearOfRelease=2022 haben.

So machen Sie das mit Dapper:

using System.Linq;

public void UpdateMultipleWithSameYear(int year, List<Movie> movies)
{
	using (var con = new SqlConnection(connectionString))
	{
		con.Execute("UPDATE Movies SET YearOfRelease=@year WHERE Id IN @ids",
			param: new { year, ids = movies.Select(m => m.Id) });
	}
}
Code language: C# (cs)

Dies ist effizienter, als mehrere UPDATE-Anweisungen auszuführen, wenn Sie nur eine benötigen.

Datensätze löschen

Das Löschen eines Datensatzes ist mit Dapper ganz einfach:

public void Delete(Movie movie)
{
	using (var con = new SqlConnection(connectionString))
	{
		con.Execute("DELETE FROM Movies WHERE Id=@id",
			param: new { id = movie.Id });
	}
}
Code language: C# (cs)

Mehrere Datensätze löschen

Wenn Sie mehrere Datensätze löschen, können Sie eine einzelne DELETE-Anweisung mit einer WHERE IN-Klausel ausführen. So geht das mit Dapper:

using System.Linq;

public void DeleteMultiple(List<Movie> movies)
{
	using (var con = new SqlConnection(connectionString))
	{
		con.Execute("DELETE FROM Movies WHERE Id IN @ids",
			param: new { ids = movies.Select(m => m.Id) });
	}
}
Code language: C# (cs)

Dies ist effizienter, als mehrere DELETE-Anweisungen auszuführen.


No