超好用的資料庫對應ORM利器:Dapper

整個四月份過於忙碌,沒有啥時間寫BLog,今天就稍微把Dapper這支StackExchange/StackOverflow團隊所研發的ORM利器翻出來,稍微濫竽充數一下。:)

在ASP.NET如今的世界中,EF(Entity Framework)大概已經把ADO.NET洗到看不見人影,但本人的心得卻是用EF不僅框架龐大,真實操作或真實編程速度說真的並不會快到哪裡(包含找Bug的時間),因此EF的開發模式並非我的首選。但,拋棄了EF意味著也要拋棄可以節省大量程式碼的Linq語法,這時候ADO.NET轉ORM(Object-Relational Mapping)的利器Dapper就是你的超強好幫手了。有許多網站在介紹Dapper的時候都會強調他的短小精幹,但事實上Dapper版本迭代至今已經慢慢的與輕薄短小扯不上關係了。

舉例我現在持有的版本1.50.4,它的大小已經來到167 KB,已經稱不上是個小DLL了。

使用ORM類別(POCO)與資料庫@具名參數

Dapper實作了IDbConnection,這意味著你可以用更簡化的ADO.NET寫法,來完成ORM的轉換。以下為範例程式碼:

using (System.Data.SqlClient.SqlConnection oConn = new System.Data.SqlClient.SqlConnection(YourDbConnectionString))
{
  oConn.Open();

  string cID = "A123456789";

  var oData = oConn.Query<UserORM>(
    "SELECT * FROM MyTable WHERE cUserID=@cUserID",
    new { cUserID = cID }
  ).FirstOrDefault();

  //噹噹噹,簡直太舒服了
  string cName = "使用者姓名:" + oData.cName;
}

public class UserORM
{
  public int iIndex { set; get; }
  public string cID { set; get; }
  public string cName { set; get; }
}

相較於傳統,你知道中間那個oData要變成資料物件,有多少程式碼要寫嗎?(回想起以前自己硬幹寫過的轉換物件程式碼(包含型別檢查),只能說是字字血淚)

使用弱型別,改採dynamic物件方式運作

這個寫法更夭壽輕鬆,連宣告ORM都不用了,只是失去了強型別的支援,你調用物件屬性必須要如履薄冰就是了(VisualStudio也沒辦法IntelliSense跟你講屬性名稱)。

using (System.Data.SqlClient.SqlConnection oConn = new System.Data.SqlClient.SqlConnection(YourDbConnectionString))
{
  oConn.Open();

  string cID = "A123456789";

  var oData = oConn.Query(
    "SELECT * FROM MyTable WHERE cUserID=@cUserID",
    new { cUserID = cID }
  ).FirstOrDefault();

  //噹噹噹,簡直夭壽舒服
  string cName = "使用者姓名:" + oData.cName;
}

有關於INSERT或UPDATE的寫法

若存在一個IEnumerable等級的資料包,利用Dapper來做寫入也是一件極度輕鬆爽快的事情,詳見下列語法(以INSERT為例):

int iResult;
using (System.Data.SqlClient.SqlConnection oConn = new System.Data.SqlClient.SqlConnection(YourDbConnectionString))
{
  oConn.Open();
  iResult = oConn.Execute($@"
INSERT INTO
  fooTable
(
  iIndex,
  cID,
  cName
)
VALUES
(
  iIndex = @iIndex,
  cID    = @cID,
  cName  = @cName
)
    ",
    new System.Collections.Generic.List<UserORM>()
    {
      new UserORM() { iIndex = 1, cID = "A001", cName = "王小明" },
      new UserORM() { iIndex = 2, cID = "A002", cName = "李小華" },
      new UserORM() { iIndex = 3, cID = "A003", cName = "陳小英" }
    }
  );
}
string cTemp = "已經插入{iResult}筆資料。";

若有需要更新的話,也無須重新製作一個新的DataORM,只要你確定這包IEnumerable資料包裡面有出現對應欄位,且資料包的內容已經更新完成即可。

oConn.Execute($@"
UPDATE
  fooTable
SET
  cName = @cName
WHERE
  iIndex = @iIndex
  ",
  oData //假設這是一整包IEnumerable<UserORM>資料
);

以上是Dapper簡單的介紹,日後若有增補的說明會再行另外發文。

Dapper ADO.NET ORM StrongTyping WeakTyping