好用的微型 ORM:Dapper
文章目錄
Dapper 是個著重效能的羽量級微型 ORM。或許說「蠅量級」更適當,因為它真的很小,很快.....
平時存取資料庫時大多用 Entity Framework,但是像 Dapper 這樣小而美且快的 ORM,在某些場合其實也相當好用(stackoverflow.com 網站就有用這元件,因為作者 Sam Saffron 曾經參與該網站的開發工作) 。
多小呢?只需一個組件:Dapper.dll,檔案才 65~75 KB 左右(v1.13),名副其實的微型 ORM。不用參考一堆額外的 DLL 組件也就比較不會被長官發現偷用 3rd-party 元件,這點真的不錯。小就是美。
多快呢?有人實測並比較過幾種 ORM,Dapper 名列前茅(Dapper 網站上也有效能比較表)。連強調速度的 ServiceStack.OrmLite 也在自家網頁的推薦名單中把 Dapper 列為首位。
好用嗎?還是試了才知道。
首先要知道的是,Dapper 不管理資料庫連線的開啟和關閉——你得自行管理連線。了解這點,就可以開始用它來存取資料了。
建立練習專案
建立一個新的 Console 應用程式專案,目標平台 .NET 4.5(Dapper 也支援 .NET 3.5 和 .NET 4.0)。接著用 NuGet 加入 Dapper 套件。
假設要存取的資料庫是 Northwind,先建立一個 POCO 類別作為對應至 Customers 資料表的 entity。程式碼如下:
範例一:查詢資料
首先在程式碼當中引用 Dapper 命名空間,然後就跟使用傳統 ADO.NET API 的步驟類似:取得連線字串、建立連線、然後執行查詢命令。
Dapper 提供了一組擴充方法,讓實作 IDbConnection 介面的物件都增加了額外的功能。從底下這張截圖可以看到,IntelliSense 顯示我的 SqlConnection 物件有額外的 Query 方法可用:
這裡使用泛型版本的 Query 方法,以便將查詢結果自動對應至先前定義好的 Customer 物件的屬性。程式碼如下:
很簡單吧?
範例二:參數式查詢
前面的範例若要改成參數式查詢,可以建立匿名型別物件,並將 SQL 命令所需的參數包在裡面,傳給 Dapper 的 Query 方法。像這樣:
範例三:執行無結果集的 SQL 命令
執行非查詢類的 SQL 命令,可使用 Execute 擴充方法:
這裡帶入參數的寫法是採用具名型別,而範例二是採用匿名型別。兩種都可以。
Dapper 提供的這種帶入 SQL 參數的作法真是方便!
範例四:呼叫預儲程序
注意這次呼叫的 Query 方法並非泛型方法,所以傳回的結果會是動態型別的物件串列。這表示我們甚至可以不用預先定義前面的 Customer 類別,也能照樣使用 Dapper 的查詢方法。當然這也意味著寫程式時少了 IntelliSense 方便的參數提示,以及編譯時期的型別安全檢查。
Dapper 的 GitHub 網頁有更多範例可以參考。
小結
這個微型 ORM 不僅執行速度快、檔案小,而且學習成本低,只要原本熟悉 ADO.NET API,便能快速上手,實在方便好用。把這套件納入開發工具箱之後,以前自己寫的一些 AdoHelper 或 SqlHelper 之類的工具類別大概就不會再去使用了。
如果你也曾這麼想:「我只需要一套簡易的 API 讓我很方便的下 SQL 命令,並且自動幫我對應成物件就好了,別的甭管。」那麼,你可能會喜歡 Dapper。
Happy coding!
平時存取資料庫時大多用 Entity Framework,但是像 Dapper 這樣小而美且快的 ORM,在某些場合其實也相當好用(stackoverflow.com 網站就有用這元件,因為作者 Sam Saffron 曾經參與該網站的開發工作) 。
多小呢?只需一個組件:Dapper.dll,檔案才 65~75 KB 左右(v1.13),名副其實的微型 ORM。不用參考一堆額外的 DLL 組件
多快呢?有人實測並比較過幾種 ORM,Dapper 名列前茅(Dapper 網站上也有效能比較表)。連強調速度的 ServiceStack.OrmLite 也在自家網頁的推薦名單中把 Dapper 列為首位。
好用嗎?還是試了才知道。
首先要知道的是,Dapper 不管理資料庫連線的開啟和關閉——你得自行管理連線。了解這點,就可以開始用它來存取資料了。
建立練習專案
建立一個新的 Console 應用程式專案,目標平台 .NET 4.5(Dapper 也支援 .NET 3.5 和 .NET 4.0)。接著用 NuGet 加入 Dapper 套件。
假設要存取的資料庫是 Northwind,先建立一個 POCO 類別作為對應至 Customers 資料表的 entity。程式碼如下:
namespace DapperDemo.Models
{
public class Customer
{
public string CustomerID { get; set; }
public string CompanyName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Phone { get; set; }
}
}
範例一:查詢資料
首先在程式碼當中引用 Dapper 命名空間,然後就跟使用傳統 ADO.NET API 的步驟類似:取得連線字串、建立連線、然後執行查詢命令。
Dapper 提供了一組擴充方法,讓實作 IDbConnection 介面的物件都增加了額外的功能。從底下這張截圖可以看到,IntelliSense 顯示我的 SqlConnection 物件有額外的 Query 方法可用:
這裡使用泛型版本的 Query 方法,以便將查詢結果自動對應至先前定義好的 Customer 物件的屬性。程式碼如下:
using System;
using System.Configuration;
using System.Data.SqlClient;
using Dapper;
namespace DapperDemo
{
class Program
{
static void Main(string[] args)
{
var cnstr = ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
using (var cn = new SqlConnection(cnstr))
{
cn.Open();
string sql = "select * from Customers where City like 'Mexico%'";
var customers = cn.Query<Models.Customer>(sql);
foreach (var cust in customers)
{
Console.WriteLine(cust.CompanyName);
}
}
}
}
}
很簡單吧?
範例二:參數式查詢
前面的範例若要改成參數式查詢,可以建立匿名型別物件,並將 SQL 命令所需的參數包在裡面,傳給 Dapper 的 Query 方法。像這樣:
var sql = "select * from Customers where City like @@City or Country=@@Country";
var parameters = new
{
City = "Mexico%" ,
Country = "UK"
};
var customers = cn.Query<Models.Customer>(sql, parameters);
範例三:執行無結果集的 SQL 命令
執行非查詢類的 SQL 命令,可使用 Execute 擴充方法:
sql = "insert into Customers (CustomerID, CompanyName, Address, City, Phone)" +
" values (@@CustomerID, @@CompanyName, @@Address, @@City, @@Phone)";
var newCust = new Models.Customer()
{
CustomerID = "Z001",
CompanyName = "MikeSoft",
Address = "大馬路黑暗巷",
City = "台北市",
Phone = "12345678"
};
int rowsChanged = cn.Execute(sql, newCust);
這裡帶入參數的寫法是採用具名型別,而範例二是採用匿名型別。兩種都可以。
Dapper 提供的這種帶入 SQL 參數的作法真是方便!
範例四:呼叫預儲程序
var spParams = new DynamicParameters();
spParams.Add("CustomerID", "ALFKI", DbType.String, ParameterDirection.Input);
var custHistories = cn.Query("CustOrderHist", spParams, commandType: CommandType.StoredProcedure);
foreach (var custHist in custHistories)
{
Console.WriteLine(custHist.ProductName);
}
注意這次呼叫的 Query 方法並非泛型方法,所以傳回的結果會是動態型別的物件串列。這表示我們甚至可以不用預先定義前面的 Customer 類別,也能照樣使用 Dapper 的查詢方法。當然這也意味著寫程式時少了 IntelliSense 方便的參數提示,以及編譯時期的型別安全檢查。
Dapper 的 GitHub 網頁有更多範例可以參考。
小結
這個微型 ORM 不僅執行速度快、檔案小,而且學習成本低,只要原本熟悉 ADO.NET API,便能快速上手,實在方便好用。把這套件納入開發工具箱之後,以前自己寫的一些 AdoHelper 或 SqlHelper 之類的工具類別大概就不會再去使用了。
如果你也曾這麼想:「我只需要一套簡易的 API 讓我很方便的下 SQL 命令,並且自動幫我對應成物件就好了,別的甭管。」那麼,你可能會喜歡 Dapper。
Happy coding!