非同步操作
DatabaseFacade 現在提供對應的非同步 API,讓原本偏向同步流程的用法,也能自然地整合到 async / await 為主的應用程式中。
可用方法
| 同步方法 | 非同步方法 | 回傳型別 |
|---|---|---|
CreateDataReader |
CreateDataReaderAsync |
Task<DbDataReader> |
CreateDataTable |
CreateDataTableAsync |
Task<DataTable> |
QueryScalar |
QueryScalarAsync |
Task<object?> |
Execute |
ExecuteAsync |
Task<int> |
所有非同步方法都會保留原本的同步 API,並額外提供 CancellationToken 參數。
非同步查詢 DataTable
using CommandExecutor executor = new CommandExecutor();
executor.CommandText = "SELECT * FROM Customers WHERE Id IN @Ids";
executor.Parameters.Add("Ids", new int[] { 1, 2, 3 });
DataTable dataTable = await executor.CreateDataTableAsync(cancellationToken);
非同步逐筆讀取資料
如果資料量較大,或想要邊讀邊處理,可以直接使用 CreateDataReaderAsync:
using CommandExecutor executor = new CommandExecutor();
executor.CommandText = "SELECT Id, Name FROM Customers WHERE Id IN @Ids";
executor.Parameters.Add("Ids", new int[] { 1, 2, 3 });
using DbDataReader reader = await executor.CreateDataReaderAsync(cancellationToken: cancellationToken);
while (await reader.ReadAsync(cancellationToken)) {
Console.WriteLine($"{reader["Id"]}, {reader["Name"]}");
}
非同步執行單一值查詢與非查詢命令
using CommandExecutor executor = new CommandExecutor();
long count = Convert.ToInt64(await executor
.SetCommandText("SELECT COUNT(1) FROM Customers")
.QueryScalarAsync(cancellationToken: cancellationToken));
int affectedRows = await executor
.SetCommandText("UPDATE Customers SET Name = @Name WHERE Id = @Id")
.Parameters.Add("Name", "小明")
.Add("Id", 1)
.GetCommandExecutor()
.ExecuteAsync(cancellationToken: cancellationToken);
與 Transaction 一起使用
Transaction 的開啟方式不變,仍然透過 BeginTransaction 進行;只要將實際執行命令的部分改成 Async 版本即可。
using CommandExecutor executor = new CommandExecutor(true);
using IDbTransaction transaction = executor.BeginTransaction();
await executor
.SetCommandText("INSERT INTO Customers (Id, Name) VALUES (@Id, @Name)")
.Parameters.Add("Id", 1)
.Add("Name", "小明")
.GetCommandExecutor()
.ExecuteAsync(ResetItems.Parameters, cancellationToken);
await executor
.SetCommandText("INSERT INTO Customers (Id, Name) VALUES (@Id, @Name)")
.Parameters.Add("Id", 2)
.Add("Name", "小王")
.GetCommandExecutor()
.ExecuteAsync(cancellationToken: cancellationToken);
transaction.Commit();
Important
若要使用 BeginTransaction,請記得將 KeepConnection 設為 true,否則會拋出 KeepConnectionRequiredException。