查詢、Mapping、參數講解完後,接著講解在增、刪、改
情況Dapper我們會使用Execute方法,其中Execute Dapper分為單次執行、多次執行
。
以單次執行來說Dapper Execute底層是ADO.NET的ExecuteNonQuery的封裝,封裝目的為了跟Dapper的Parameter、緩存
功能搭配使用,代碼邏輯簡潔明瞭這邊就不做多說明,如圖片
這是Dapper一個特色功能,它簡化了集合操作Execute之間的操作,簡化了代碼,只需要 : connection.Execute("sql",集合參數);
。
至於為何可以這麼方便,以下是底層的邏輯 :
一個共同DbCommand
提供foreach迭代使用,避免重複建立浪費資源CreateParameter > 對Parameter賦值 > 使用Parameters.Add添加新建的參數
,以下是Emit IL轉成的C#代碼 : public static void ParamReader(IDbCommand P_0, object P_1)
{
var anon = (<>f__AnonymousType0<int>)P_1;
IDataParameterCollection parameters = P_0.Parameters;
IDbDataParameter dbDataParameter = P_0.CreateParameter();
dbDataParameter.ParameterName = "V";
dbDataParameter.DbType = DbType.Int32;
dbDataParameter.Direction = ParameterDirection.Input;
dbDataParameter.Value = anon.V;
parameters.Add(dbDataParameter);
}
foreach
該集合參數 > 除了第一次外,每次迭代清空DbCommand的Parameters > 重新呼叫同一個
動態方法添加Parameter > 送出SQL查詢實作方式簡潔明瞭,並且細節考慮共用資源避免浪費(e.g共用同一個DbCommand、Func
),但遇到大量執行追求效率需求情況,需要特別注意此方法每跑一次對資料庫送出一次reqesut
,效率會被網路傳輸拖慢,所以這功能被稱為「多次執行」而不是「批量執行」
的主要原因。
舉例,簡單Execute插入十筆資料,查看SQL Profiler可以看到系統接到10次Reqeust:
using (var cn = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=SSPI;Initial Catalog=Northwind;"))
{
cn.Open();
using (var tx = cn.BeginTransaction())
{
cn.Execute("create table #T (V int);", transaction: tx);
cn.Execute("insert into #T (V) values (@V)", Enumerable.Range(1, 10).Select(val => new { V = val }).ToArray() , transaction:tx);
var result = cn.Query("select * from #T", transaction: tx);
Console.WriteLine(result);
}
}