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
































