Dapper使用技巧分享


Dapper是輕量級的.net ORM框架,配合linq和泛型,讓C#操作數據的代碼簡潔、高效又靈活!最近的工作項目中使用了Dapper,在這里分享一些實用技巧。閱讀之前需要了解一些基本的使用方法,參見官網http://dapper-tutorial.net/ 。

  • 寫可撤銷的查詢:

你的應用程序應該給用戶提供各種“取消”的功能,這就在包括了查詢數據的時候撤銷一條正在執行的查詢,Dapper像很多ORM一樣提供了這個操作,看看這段代碼:

// using Dapper;

var products = sqlConnection.QueryAsync<Product>(new CommandDefinition(
                    queryProducts,
                    new { Type = "SomeType" },
                    commandTimeout: 60,
                    cancellationToken: myToken)).Result.ToList();

這里Product是定義好的數據類,queryProducts是查詢文本,myToken是定義好的Task的CancellationToken。這段代碼使用QueryAsync異步方法實現了可撤銷的查詢操作,開發者需要把控制撤銷的myToken傳給CommandDefinition的可選參數cancellationToken。使用代碼之前,要了解一下C#的Task概念。

另外值得注意的是,查詢的TimeOut可以通過commandTimeout設置(默認30s)。

  • 使用事務:

事務是數據庫的重要概念,Dapper對事務提供了很好的支持,看看這段代碼:

1 // using System.Linq;
2 // using System.Data.SqlClient;
3 using (SqlTransaction tran = sqlConn.BeginTransaction())
4 {
5     var pars = ProductsWithNewPrice.Select(t => { return new { t.ProductID, t.Price }; });
6     sqlConn.Execute(UpdateProductPrice, pars, transaction: tran);
7     tran.Commit();
8 }

通過喜聞樂見的using形式執行一段事務,這里假設ProductsWithNewPrice是一個具有新價格的Product類的集合,事務的目的是把這些新價格通過Update語句更新到數據庫中。第5行用linq取出了具有ProductID和Price字段的臨時類型的集合,這個集合作為下面一行所執行的sql語句們的參數。UpdateProductPrice是查詢文本,應該是類似這樣的“UPDATE dbo.Product set Price = @Price WHERE ProductID = @ProductID;”。因為使用了transaction,pars集合中的所有參數對應的"UPDATE"語句會在同一個事務中完成。

  • 從數據庫取UTC時間:

我們假設工作環境中數據庫一直使用UTC時間(現實經常是這樣),我們寫的代碼經常從數據庫中讀取時間並轉化成C#的DateTime結構。轉化的時候Datretime.Kind屬性經常被忽略,這可能導致隨后的使用中把時間值當做本地時間。要確保避免這樣的錯誤,我們可以做一個設定,把Dapper取到的值指定DateTimeKind為UTC,並把正確的UTC時間存儲到數據庫。代碼是這樣的,先創建DateTimeHandler類:

    public class DateTimeHandler : SqlMapper.TypeHandler<DateTime>
    {
        public override void SetValue(IDbDataParameter parameter, DateTime value)
        {
            parameter.Value = DateTime.SpecifyKind(value, DateTimeKind.Utc);
        }

        public override DateTime Parse(object value)
        {
            return DateTime.SpecifyKind(Convert.ToDateTime(value), DateTimeKind.Utc);
        }
    }

然后在你的類的構造函數中加入這行:

            SqlMapper.AddTypeHandler(new DateTimeHandler());

這樣,Dapper取到的時間值和通過Dapper保存到數據庫的時間值就都是UTC時間了。

  • 使用字符串變量名拼接多個SQL語句

請看下面這段代碼。這里使用加號“+”拼接了兩個不同功能的SQL語句,並且讓兩個語句都可以復用!我認為這在指定情景中是一個很好的實踐。

    var nextWorkID = sqlConn.Query<int>(SubmitCurrentWork + FindNextWorkID, new { currentWorkID, currentWorkResult }).FirstOrDefault();

不過這樣使用Dapper有兩個要求:

  1. 每個SQL字符串變量都要以分號結尾。
  2. 不同SQL語句中的變量名必須是一樣的。

滿足了這兩個要求才能寫上面那樣的代碼。上面代碼中的SQL字符串變量可以是下面這樣:

    string SubmitCurrentWork = "UPDATE dbo.Works SET WorkResult = @currentWorkResult, Status = 'Done' WHERE ID = @currentWorkID;";
    string FindNextWorkID = "SELECT TOP 1 ID FROM dbo.Works WHERE Status != 'Done';"; // 如果這里有名為@currentWorkResult或@currentWorkID的變量,其用途/含義要和上面的語句一致

 以上就是自己的一點經驗總結,歡迎拍磚!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM