[Dapper] 利用 Dapper.Contrib 簡化 CRUD 工作

Dapper.Contrib 另外提供 CRUD 的擴充方法,針對 IDbConnection 型別進行擴充,他會根據 Model 定義自動幫我們渲染 SQL 語句,對於簡單的 CRUD 情境相當合用,從原本需要 Insert Command 以及 Parameter 的寫法,變成只需要 Insert(Model)

原本的寫法,可參考:[C#.NET] ORM - Dapper 強大的 dynamic parameters

開發環境

  • VS 2017 15.9.5
  • .NET Framework 4.7.2
  • Dapper.Contrib 16.0.1 

安裝 Dpaaer.Contrib

  • Install-Package Dapper.Contrib

實作

開始之前要定義 Model,因為它是透過這個 Model 來幫我們渲染 SQL 語法

Member Model 定義如下

[Table("Member")]
internal class Member
{
    [Key]
    [Dapper.Contrib.Extensions.ExplicitKey]
    public Guid Id { getset}
 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Dapper.Contrib.Extensions.Computed]
    public long SequenceId { getset}
 
    [StringLength(100)]
    public string Name { getset}
 
    public int Age { getset}
}

他跟 EF 一樣是根據 PK 來渲染 SQL 語法,不過指適合簡單的情境,較複雜的還是得自己控制

  • Dapper.Contrib.Extensions.Key:預設會把 Id 或是有[Dapper.Contrib.Extensions.Key]當成是自動運算的欄位,而不產生語法
  • Dapper.Contrib.Extensions.ExplicitKey:不是自動運算的欄位,要產生語法
  • Dapper.Contrib.Extensions.Computed:自動運算的欄位,不產生語法
  • Table("Member"):預設使用Class Name 當 Table Name,這明確指定 Table Name,不使用 Class Name 當 Table Name

可透過 SQL Profiler 觀察,這些 Attribute 的變化

範例

為了測試真實的DB,測試專案做了比較多的動作,這裡只貼出部分代碼,需要看完整的請到以下連結

範例專案

https://github.com/yaochangyu/sample.dotblog/tree/master/ORM/Dapper/Simple.DapperCUD
 

新增

[TestMethod]
public void Insert_Test()
{
    using (var dbConnection = DbManager.CreateConnection())
    {
        var memberToDb = new Member
        {
            Id = Guid.NewGuid(),
            Name = "Yao",
            Age = 12
        };
        var count = dbConnection.Insert(memberToDb);
        Assert.IsTrue(count > 0);
    }
}

編輯

[TestMethod]
public void Update_Test()
{
    var member = Insert();
    var expected = "小章";
    using (var dbConnection = DbManager.CreateConnection())
    {
        member.Name = expected;
        dbConnection.Update(member);
        NameShouldBe(expected);
    }
}

刪除

[TestMethod]
public void Delete_Test()
{
    var member = Insert();
    using (var dbConnection = DbManager.CreateConnection())
    {
        dbConnection.Delete(new Member {Id = member.Id});
        ShouldBeNull();
    }
}

查詢

[TestMethod]
public void Get_Test()
{
    var member = Insert();
    using (var dbConnection = DbManager.CreateConnection())
    {
        var actual = dbConnection.Get<Member>(member.Id);
        member.Should()
              .BeEquivalentTo(actual,
                              options => options.Excluding(=> o.SequenceId));
    }
}

 

參考

https://github.com/StackExchange/Dapper/tree/master/Dapper.Contrib

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo