EF 太重?Dapper 太累?.NET項目ORM該怎么選?
在搞 .NET 數(shù)據(jù)驅(qū)動項目時,選 Dapper 還是 Entity Framework(EF),幾乎是每個團隊都要面對的問題。
它們都是好工具,但定位完全不同:
- Dapper 是“狙擊槍”——輕、快、準(zhǔn),但得你自己瞄
- EF 是“全自動步槍”——開箱即用,但有點重
選哪個?別看誰吹得響,要看你的項目到底需要啥:
? 性能優(yōu)先?
? 開發(fā)速度優(yōu)先?
? 團隊 SQL 水平如何?
下面咱就掰開揉碎,說說怎么選,還附上真實 CRUD 代碼,讓你一眼看懂差異。
Dapper:輕量高性能,SQL 老炮兒的最愛
Dapper 是個“微型 ORM”,說白了就是給 IDbConnection 加了點糖——讓你能用對象傳參、自動映射結(jié)果,但SQL 還是你自己寫。
適合誰用?
- 高并發(fā) API / 微服務(wù)(比如秒殺、支付)
- 項目里一堆復(fù)雜 SQL(報表、多表 JOIN、存儲過程)
- 老系統(tǒng)遷移,SQL 已經(jīng)寫好,不想重寫
優(yōu)點(為啥選它?)
- 快! 抽象層薄如紙,性能基本等于原生 ADO.NET
- 透明! 你寫的 SQL 就是最終執(zhí)行的 SQL,不怕 EF “偷偷加 LEFT JOIN”
- 輕! NuGet 包就幾百 KB,不帶任何“全家桶”依賴
- 自由! 想怎么寫 SQL 都行,子查詢、CTE、窗口函數(shù)隨便上
缺點(代價是啥?)
- SQL 得手寫:表一多、字段一改,到處改 SQL,維護成本高
- 沒高級功能:自動遷移?變更跟蹤?LINQ?統(tǒng)統(tǒng)沒有
- 容易出錯:拼錯字段名?運行時才報錯,編譯器不幫你
示例:Dapper 的 CRUD —— SQL 全暴露,性能拉滿
using System.Data;
using System.Threading.Tasks;
using Dapper;
using Microsoft.Data.Sqlite;
publicclassDapperUserRepository
{
privatereadonlystring _connectionString = "Data Source=app.db";
private IDbConnection CreateConnection() => new SqliteConnection(_connectionString);
public async Task AddUserAsync(User user)
{
conststring sql = "INSERT INTO Users (Name, Email) VALUES (@Name, @Email)";
usingvar connection = CreateConnection();
await connection.ExecuteAsync(sql, user);
}
publicasync Task<User?> GetUserByIdAsync(int id)
{
conststring sql = "SELECT * FROM Users WHERE Id = @Id";
usingvar connection = CreateConnection();
returnawait connection.QuerySingleOrDefaultAsync<User>(sql, new { Id = id });
}
// ... Update / Delete / GetAll 類似
}? 好處:每行 SQL 清清楚楚,性能瓶頸一眼定位? 代價:改個表結(jié)構(gòu)?所有相關(guān) SQL 都得手動改
Entity Framework:開發(fā)效率神器,業(yè)務(wù)建模首選
EF 是個“全功能 ORM”,目標(biāo)就一個:讓你像操作 C# 對象一樣操作數(shù)據(jù)庫,SQL?它幫你生成。
適合誰用?
- 企業(yè)級應(yīng)用(CRM、ERP、后臺系統(tǒng))
- 數(shù)據(jù)模型復(fù)雜,實體關(guān)系多(一對多、多對多)
- 團隊里有新手,不想讓他們手寫 SQL
優(yōu)點(為啥選它?)
- 開發(fā)快! 增刪改查幾行 LINQ 搞定,不用寫 SQL
- 可維護! 改字段?改實體類就行,EF 自動同步
- 功能全! 自動遷移、變更跟蹤、懶加載、數(shù)據(jù)播種……全都有
- 安全! LINQ 編譯時檢查,拼錯字段名直接報錯
缺點(代價是啥?)
- 性能略慢:抽象層厚,生成的 SQL 有時不夠優(yōu)(比如 N+1 問題)
- 黑盒感:復(fù)雜查詢時,你不知道 EF 到底發(fā)了啥 SQL
- 調(diào)優(yōu)難:想優(yōu)化 SQL?得用
.FromSqlRaw()或手寫,反而更麻煩
示例:EF 的 CRUD —— 零 SQL,代碼清爽
public classEfUserRepository
{
privatereadonly AppDbContext _context;
public EfUserRepository(AppDbContext context)
{
_context = context;
}
public async Task AddUserAsync(User user)
{
_context.Users.Add(user);
await _context.SaveChangesAsync();
}
publicasync Task<User?> GetUserByIdAsync(int id)
{
returnawait _context.Users.FindAsync(id); // 自動轉(zhuǎn)成 SELECT ... WHERE Id = @id
}
// ... Update / Delete / GetAll 類似
}? 好處:代碼簡潔,新人也能看懂,改需求快? 代價:高并發(fā)場景下,可能不如 Dapper 猛
Dapper vs EF 對比表 —— 一目了然
特性 | Dapper | Entity Framework |
類型 | 微型 ORM(輕量) | 完整 ORM(重型) |
性能 | ? 極致快(接近原生) | ?? 略慢(抽象層開銷) |
SQL 控制 | ? 完全手動,100% 掌控 | ?? 自動生成,有時不夠優(yōu) |
開發(fā)效率 | ?? 中等(要寫 SQL) | ? 高(LINQ + 自動跟蹤) |
高級功能 | ? 無(只有 CRUD) | ? 全(遷移、跟蹤、LINQ 等) |
適合團隊 | SQL 老手、性能敏感型 | 業(yè)務(wù)復(fù)雜、追求可維護性 |
老司機終極建議 —— 別二選一,可以“混著用”!
“Dapper 和 EF 不是對手,是搭檔?!?/p>
推薦混合策略:
- 用 EF 做寫操作:業(yè)務(wù)邏輯復(fù)雜,需要變更跟蹤、事務(wù)管理
- 用 Dapper 做讀操作:高性能查詢、報表、聚合統(tǒng)計
比如:
// 寫用戶:用 EF,保證數(shù)據(jù)一致性
userService.CreateUser(user);
// 查用戶列表(帶復(fù)雜篩選):用 Dapper,性能拉滿
var users = dapperRepository.GetUsersWithFilters(...);選型前必做:跑個 POC(概念驗證)!
別光聽別人說,自己測:
- 模擬真實數(shù)據(jù)量(10萬行 vs 1000 行結(jié)果天差地別)
- 測并發(fā) QPS(Dapper 優(yōu)勢在高并發(fā))
- 算開發(fā)成本(EF 初期快,Dapper 后期維護難)
總結(jié) —— 一句話決策指南
要速度、要控制、SQL 老手?選 Dapper。
要效率、要維護、業(yè)務(wù)復(fù)雜?選 EF。
既要又要?混合用,才是真·高手。

































