iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
4
Software Development

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

【深入Dapper.NET源碼】錯誤SQL字串拼接方式,會導致效率慢、內存洩漏

  • 分享至 

  • xImage
  •  

了解實作邏輯後,接著延伸一個Dapper使用的重要觀念,SQL字串為緩存重要Key值之一,假如不同的SQL字串,Dapper會為此建立新的動態方法、緩存,所以使用不當情況下就算使用StringBuilder也會造成效率慢、內存洩漏問題

https://ithelp.ithome.com.tw/upload/images/20190916/20105988lAFBAWbhS6.png

至於為何要以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();
        }  
    }
}

zeiAPVJ

要避免此問題,只需要保持一個原則重複利用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();
        }  
    }
}

4IR5M47


上一篇
【深入Dapper.NET源碼】Dapper 效率快關鍵之一 : Cache 緩存原理
下一篇
【深入Dapper.NET源碼】Dapper SQL正確字串拼接方式 : Literal Replacement
系列文
🌊 進階學習 ADO.NET、Dapper、Entity Framework 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言