了解實作邏輯後,接著延伸一個Dapper使用的重要觀念,SQL字串
為緩存重要Key值之一,假如不同的SQL字串,Dapper會為此建立新的動態方法、緩存,所以使用不當情況下就算使用StringBuilder也會造成效率慢、內存洩漏問題
。
至於為何要以SQL字串當其中一個關鍵Key,而不是單純使用Mapping類別的Handle,其中原因之一是跟查詢欄位順序
有關,在前面有講到,Dapper使用「結果反推程式碼」
方式建立動態方法,代表說順序跟資料都必須要是固定
的,避免SQL Select欄位順序不一樣又使用同一組動態方法,會有A欄位值給B屬性
錯值大問題。
最直接解決方式,對每個不同SQL字串建立不同的動態方法,並保存在不同的緩存。
舉例,以下代碼只是簡單的查詢動作,查看Dapper Cache數量卻達到999999個,如Gif動畫顯示
using (var cn = new SqlConnection(@"connectionString"))
{
for (int i = 0; i < 999999; i++)
{
var guid = Guid.NewGuid();
for (int i2 = 0; i2 < 2; i2++)
{
var result = cn.Query<User>($"select '{guid}' ").First();
}
}
}
要避免此問題,只需要保持一個原則重複利用SQL字串
,而最簡單方式就是參數化
, 舉例 : 將上述代碼改成以下代碼,緩存數量降為1
,達到重複利用目的 :
using (var cn = new SqlConnection(@"connectionString"))
{
for (int i = 0; i < 999999; i++)
{
var guid = Guid.NewGuid();
for (int i2 = 0; i2 < 2; i2++)
{
var result = cn.Query<User>($"select @guid ",new { guid}).First();
}
}
}