Dapper 是 Stack Overflow 團隊開發的微型 ORM,單一檔案 SqlMapper.cs、編譯後僅 40KB,效能逼近 IDataReader,支援多種資料庫、多對多映射、零侵入式設計,深受開發者喜愛。
// 連線工廠
IDbConnection OpenConn() => new SqlConnection("Server=.;DB=Test;User=sa;Pwd=sa;");
public IEnumerable GetCategories()
{
using var conn = OpenConn();
return conn.Query("SELECT * FROM Category ORDER BY Id DESC");
}
public Category GetCategory(int id)
{
using var conn = OpenConn();
return conn.Query("SELECT * FROM Category WHERE Id=@id", new { id })
.SingleOrDefault();
}
public int Insert(Category c)
{
using var conn = OpenConn();
const string sql = "INSERT INTO Category(Name, ParentId) VALUES(@Name, @ParentId); SELECT CAST(SCOPE_IDENTITY() as int)";
return conn.QuerySingle(sql, c); // 自動取回新增 ID
}
public int Update(Category c)
{
using var conn = OpenConn();
return conn.Execute("UPDATE Category SET Name=@Name, ParentId=@ParentId WHERE Id=@Id", c);
}
public int Delete(int id)
{
using var conn = OpenConn();
return conn.Execute("DELETE FROM Category WHERE Id=@id", new { id });
}
public class Article
{
public int Id { get; set; }
public string Title { get; set; }
public Category Category { get; set; } // 巢狀物件
}
public IList GetArticlesWithCategory()
{
using var conn = OpenConn();
const string sql = @"
SELECT a.Id, a.Title, a.CategoryId,
c.Id, c.Name, c.ParentId
FROM Article a LEFT JOIN Category c ON a.CategoryId = c.Id";
return conn.Query(sql,
(article, category) => { article.Category = category; return article; },
splitOn: "Id") // 第二個 Id 為 Category.Id
.ToList();
}
public int DeleteCategoryAndArticles(int catId)
{
using var conn = OpenConn();
conn.Open();
using var tran = conn.BeginTransaction();
try
{
var rows = conn.Execute("DELETE FROM Article WHERE CategoryId=@catId", new { catId }, tran);
rows += conn.Execute("DELETE FROM Category WHERE Id=@id", new { id = catId }, tran);
tran.Commit();
return rows;
}
catch
{
tran.Rollback();
throw;
}
}
new { id = 1, name = "test" } 匿名型別或 DynamicParameters。OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY。conn.QueryMultiple(sql) 依序 Read() 。conn.Execute("sp_BulkInsert", new { items = dt.AsTableValuedParameter("dbo.MyType") }, commandType: CommandType.StoredProcedure)。buffered: false 串流大量資料避免 OOM。追求效能、喜歡掌控 SQL、專案不需完整 ORM 變更追蹤、遷移專案逐步替換 ADO.NET 代碼。