C# – Esecuzione di query SQL di base con Dapper

C# – Esecuzione di query SQL di base con Dapper

Ecco un esempio di utilizzo di Dapper per eseguire una query SELECT di base:

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 astrae il codice ripetitivo coinvolto nell'esecuzione di query SQL, inclusi i parametri di mappatura e i risultati delle query. Lo fa senza alcuna configurazione (esegue la mappatura usando la riflessione).

In questo articolo mostrerò altri esempi di utilizzo di Dapper in scenari comuni, come l'aggiunta di parametri di query e l'inserimento di record.

Nota:se non l'hai già fatto, aggiungi il pacchetto nuget Dapper .

Aggiunta di parametri di query

Per aggiungere parametri di query con Dapper, passa un oggetto per il param argomento:

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)

Puoi passare qualsiasi oggetto, inclusi i tipi anonimi (come mostrato sopra). Dapper proverà a mappare le proprietà dal param oggetto ai segnaposto dei parametri (es. "@year") nella query.

Richiamo di un processo memorizzato

Supponiamo che tu voglia chiamare il seguente processo memorizzato:

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

Ecco un esempio di come chiamare questo processo memorizzato con Dapper:

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)

Specificare il nome del processo memorizzato, eventuali parametri e impostare l'argomento commandType su CommandType.StoredProcedure.

Inserimento record

Ecco un esempio di inserimento di un singolo record di film:

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)

Gli inserimenti sono un po' noiosi da codificare perché l'istruzione INSERT è molto dettagliata rispetto ad altre istruzioni SQL. Esistono librerie di estensioni per Dapper che astraggono le operazioni CRUD in modo da non dover scrivere SQL, ma personalmente non le uso. Uno dei vantaggi di Dapper è che esegue la query SQL che scrivi, quindi non ci sono sorprese.

Essere in grado di passare l'oggetto filmato per il param argomento aiuta, poiché non è necessario digitare l'elenco dei parametri. Per scrivere l'istruzione INSERT, di solito utilizzo Tabella degli script come> INSERT INTO in SSMS per creare uno script del punto di partenza o generare le query utilizzando i metadati.

Ottenere il valore di identità inserito

Quando inserisci un record in una tabella con una colonna identity, puoi ottenere il valore identity inserito aggiungendo OUTPUT INSERTED.Id alla query. Usa ExecuteScalar() per ottenere il singolo valore restituito:

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)

Inserimento di più record

Quando si passa un elenco di oggetti per il param argomento, Dapper eseguirà la query SQL per ogni oggetto nell'elenco:

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)

L'esecuzione di molte istruzioni INSERT in sequenza può davvero degradare le prestazioni. Assicurati di testare le prestazioni del tuo codice se prevedi di inserire spesso molti dati come questo. Consiglio vivamente di eseguire un BULK INSERT se si verificano problemi di prestazioni.

Aggiornamento record

Ecco un esempio di come aggiornare un record con Dapper:

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)

Puoi mantenere l'istruzione UPDATE il più semplice possibile includendo solo le colonne minime nella query. Se non è necessario che una colonna sia nell'elenco di aggiornamento o nella clausola where, lasciala fuori.

Aggiornamento di più record

Se stai aggiornando più record con valori diversi, dovrai eseguire più istruzioni UPDATE. Ad esempio, supponiamo di voler impostare:

  • Film A YearOfRelease=2021
  • Film B YearOfRelease=2022

Per farlo con Dapper, puoi passare un elenco per il param discussione. Eseguirà l'istruzione UPDATE per ogni oggetto filmato nell'elenco:

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)

Se stai aggiornando più record con lo stesso valore, puoi eseguire una singola istruzione UPDATE con una clausola WHERE IN. Ad esempio, supponiamo che tu voglia aggiornare diversi film per avere YearOfRelease=2022.

Ecco come farlo con 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)

Questo è più efficiente rispetto all'esecuzione di più istruzioni UPDATE quando ne hai solo bisogno.

Eliminazione dei record

L'eliminazione di un record è semplice con Dapper:

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)

Eliminazione di più record

Quando elimini più record, puoi eseguire una singola istruzione DELETE con una clausola WHERE IN. Ecco come farlo con 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)

Questo è più efficiente rispetto all'esecuzione di più istruzioni DELETE.


No