C# – Dapper で挿入された ID 値を取得する

ID 列を持つテーブルにレコードを挿入すると、ID 列の値が自動的に生成されます。挿入された ID 値を取得する最も簡単な方法は、挿入ステートメントに OUTPUT INSERTED. を配置することです:

INSERT INTO Orders
(CustomerId, Status, StoreId)
OUTPUT INSERTED.OrderId
VALUES
(@CustomerID, @Status, @StoreId)
Code language: SQL (Structured Query Language) (sql)

Dapper で出力値を取得するには、ExecuteScalar():

を使用します。
public int InsertOrder(Order order)
{
	using (var con = new SqlConnection(ConnectionString))
	{
		var identity = con.ExecuteScalar<int>(INSERT_SQL, param: order);
		return identity;
	}
}
Code language: C# (cs)

これにより、新しい行が挿入され、生成された ID 整数が返されます:

75129Code language: plaintext (plaintext)

注:これは QuerySingle() を使用することと同じです。私は ExecuteScalar() を使用することを好みます。その唯一の目的は単一の値を取得することであり、意図が明確であるためです。 QuerySingle は通常、単一の行を取得してオブジェクトにマップするために使用されます。

複数の列を出力する場合は QuerySingle() を使用してください

挿入された行から複数​​の列を返したいとしましょう。挿入ステートメントで OUTPUT INSERTED.* を使用できます (または、表示されているように列名を入力します)。

INSERT INTO Orders
(CustomerId, Status, StoreId)
OUTPUT INSERTED.OrderId, INSERTED.CustomerId, INSERTED.Status, INSERTED.StoreId
VALUES
(@CustomerID, @Status, @StoreId)
Code language: SQL (Structured Query Language) (sql)

Dapper では、QuerySingle() を使用して出力列をオブジェクトにマップします。

public Order InsertOrder(Order orderToInsert)
{
	using (var con = new SqlConnection(ConnectionString))
	{
		var insertedOrder = con.QuerySingle<Order>(INSERT_SQL, param: orderToInsert);
		return insertedOrder;
	}
}
Code language: C# (cs)

これにより、新しい注文行が挿入され、Dapper が Order オブジェクト (JSON として表示) にマップするすべての列が返されます。

{
  "OrderId": 75131,
  "CustomerId": 1,
  "Status": "New",
  "StoreId": 1
}Code language: JSON / JSON with Comments (json)

更新、削除、および複数の出力行

挿入された値を出力できるのと同じ方法で、更新された値と削除された値を出力できます。データを変更するたびに、INSERTED および DELETED の特別な一時テーブルで値を使用できます。

  • INSERT – 挿入した値は INSERTED で使用できます。
  • UPDATE – 古い値は DELETED にあります。新しい値は INSERTED にあります。
  • DELETE – 削除した値は DELETED にあります。

これらの値は、変更された行ごとです。これは、複数の行を変更し、INSERTED/DELETED から値を出力する場合、出力値の複数の行が返されることを意味します。 Dapper では、Query() を使用して複数行の出力を取得します。

たとえば、キャンセルされた一連の注文を削除していて、削除された注文 ID を出力したいとします。

まず、削除ステートメントに OUTPUT DELETED.<列名> を入れます:

DELETE FROM Orders
OUTPUT DELETED.OrderId
WHERE [Status]='Canceled'
Code language: SQL (Structured Query Language) (sql)

Dapper では、Query() を使用して、削除された注文 ID をすべて取得します。

public IEnumerable<int> DeleteCanceledOrders()
{
	using (var con = new SqlConnection(ConnectionString))
	{
		var deletedOrderIds = con.Query<int>(DELETE_SQL);
		return deletedOrderIds;
	}
}
Code language: C# (cs)

これにより、複数の注文が削除され、次の削除された注文 ID が出力されます (JSON 配列として表示):

[
  43659,
  43660,
  43661
]Code language: JSON / JSON with Comments (json)