Execute: Insert, Update and Delete
Execute runs INSERT, UPDATE and DELETE and returns how many rows changed. To get a new row's id back, query it with QuerySingle<int>.
Journeyman · C# · T-SQL · Updated
After this lesson you can
- Change data with Execute, and use the number of rows it returns
- Insert a row and get its new id back with QuerySingle<int> and SCOPE_IDENTITY
Key takeaways
ExecuterunsINSERT,UPDATEandDELETEand returns how many rows changed.- An
UPDATEorDELETEfor an id that doesn't exist changes 0 rows without an error, so check the count, as inreturn rows == 1;. - To get a new row's id, follow the
INSERTwithSELECT CAST(SCOPE_IDENTITY() AS int);and read it withQuerySingle<int>. - Pass a list of parameter objects, and
Executeruns the SQL once per item and returns the total rows changed.
Reading uses Query. Changing data uses Execute: it runs the SQL and returns how many rows it changed, just like ADO.NET's ExecuteNonQuery.
Insert, update, delete
This program adds a product, raises its price, deletes it, and prints how many rows each step changed. It cleans up after itself, so Northwind ends as it started.
using Dapper;
using Microsoft.Data.SqlClient;
string connectionString = "Server=localhost;Database=Northwind;Integrated Security=true;TrustServerCertificate=true;";
using SqlConnection connection = new SqlConnection(connectionString);
int newId = connection.QuerySingle<int>("""
INSERT INTO Products (ProductName, CategoryId, UnitPrice)
VALUES (@ProductName, @CategoryId, @UnitPrice);
SELECT CAST(SCOPE_IDENTITY() AS int);
""", new { ProductName = "Hot Chocolate", CategoryId = 1, UnitPrice = 5.99m });
Console.WriteLine( quot;Added a product: {newId > 77}");
int updated = connection.Execute(
"UPDATE Products SET UnitPrice = UnitPrice + 1 WHERE ProductId = @ProductId;", new { ProductId = newId });
Console.WriteLine( quot;Rows updated: {updated}");
decimal price = connection.ExecuteScalar<decimal>(
"SELECT UnitPrice FROM Products WHERE ProductId = @ProductId;", new { ProductId = newId });
Console.WriteLine( quot;New price: {price:0.00}");
int deleted = connection.Execute(
"DELETE FROM Products WHERE ProductId = @ProductId;", new { ProductId = newId });
Console.WriteLine( quot;Rows deleted: {deleted}");
Added a product: True
Rows updated: 1
New price: 6.99
Rows deleted: 1
Getting the new id
An INSERT doesn't return anything, but the new row's IDENTITY value is often needed: to show the new product's page, or to add rows that refer to it. Follow the INSERT with SELECT CAST(SCOPE_IDENTITY() AS int); in the same SQL, and read that one value with QuerySingle<int>, as above.
(SCOPE_IDENTITY() is the id just made by your own statement. The CAST makes it an int, the type of the column.)
Using the count
Execute's return value tells you whether anything happened. An UPDATE or DELETE for an id that doesn't exist changes 0 rows, without an error. A DAO can turn that into a bool:
public bool Delete(int productId)
{
using SqlConnection connection = new SqlConnection(connectionString);
int rows = connection.Execute(
"DELETE FROM Products WHERE ProductId = @ProductId;", new { ProductId = productId });
return rows == 1;
}
The caller then knows whether the product existed: a web app can answer 404 Not Found when it didn't.
Many rows in one call
Pass a list of parameter objects, and Execute runs the SQL once per item, returning the total rows changed:
using Dapper;
using Microsoft.Data.SqlClient;
string connectionString = "Server=localhost;Database=Northwind;Integrated Security=true;TrustServerCertificate=true;";
using SqlConnection connection = new SqlConnection(connectionString);
var newShippers = new[]
{
new { CompanyName = "Rapid Couriers", Phone = "(503) 555-0199" },
new { CompanyName = "Night Owl Freight", Phone = "(503) 555-0123" }
};
int added = connection.Execute(
"INSERT INTO Shippers (CompanyName, Phone) VALUES (@CompanyName, @Phone);", newShippers);
Console.WriteLine( quot;Shippers added: {added}");
int removed = connection.Execute(
"DELETE FROM Shippers WHERE CompanyName IN ('Rapid Couriers', 'Night Owl Freight');");
Console.WriteLine( quot;Shippers removed: {removed}");
Shippers added: 2
Shippers removed: 2
(var here holds an array of anonymous objects, a type with no name you could write.)
Check yourself
2 questions to try on the lesson page.
So what
Execute for changes, its count to see what happened, and QuerySingle<int> with SCOPE_IDENTITY() for a new row's id. That's every write a DAO needs.
Key terms
- Execute()
- SCOPE_IDENTITY