iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 21
1
Software Development

🌊 進階學習 ADO.NET、Dapper、Entity Framework 系列 第 21

【深入Dapper.NET源碼】 單次、多次 Execute 底層原理

查詢、Mapping、參數講解完後,接著講解在增、刪、改情況Dapper我們會使用Execute方法,其中Execute Dapper分為單次執行、多次執行

單次Execute

以單次執行來說Dapper Execute底層是ADO.NET的ExecuteNonQuery的封裝,封裝目的為了跟Dapper的Parameter、緩存功能搭配使用,代碼邏輯簡潔明瞭這邊就不做多說明,如圖片
20191002144453.png

「多次」Execute

這是Dapper一個特色功能,它簡化了集合操作Execute之間的操作,簡化了代碼,只需要 : connection.Execute("sql",集合參數);

至於為何可以這麼方便,以下是底層的邏輯 :

  1. 確認是否為集合參數
    20191002150155.png
  2. 建立一個共同DbCommand提供foreach迭代使用,避免重複建立浪費資源
    20191002151237.png
  3. 假如是集合參數,建立Emit IL動態方法,並放在緩存內利用
    20191002150349.png
  4. 動態方法邏輯是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);
	}
  1. 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);
    }
}

20191002151658.png


上一篇
【深入Dapper.NET源碼】DynamicParameter 底層原理、自訂實作
下一篇
【深入Dapper.NET源碼】ExecuteScalar應用
系列文
🌊 進階學習 ADO.NET、Dapper、Entity Framework 30

尚未有邦友留言

立即登入留言