從傳統代碼生成三層 (動軟) 遷移至 ORM 驅動的領域模型三層 (NHibernate),本文對比兩種架構在**變更成本、職責劃分、數據訪問方式**上的差異,並給出 NHibernate 三層落地建議。
1. 動軟三層架構 (代碼生成驅動)

結構
- IDAL:介面層,定義數據訪問契約。
- SQLServerDAL / OracleDAL / DB2DAL:具體實現,屏蔽數據庫差異。
- BLL:業務邏輯層,封裝 DAL 調用,對表示層暴露業務操作。
- 表示層:ASPX 頁面,調用 BLL 獲取數據,GridView 綁定顯示。
痛點
- 變更擴散:加一個查詢 → IDAL 加介面 → DAL 實現 → BLL 包裝 → 三層同步修改。
- 字段變更重生成:表結構變動需重新生成代碼,或手動逐層修改。
- BLL 職責混雜:動軟為每表生成一個 BLL 類,但:
- 部分表無業務邏輯 (如公司/個人信息表) → 純數據通道。
- 部分業務跨表 (如登錄需 User+Role+Permission) → 單表 BLL 無法表達。
2. NHibernate 三層結構 (領域模型驅動)

結構
- Model (Domain Entities):實體類,**封裝數據操作方法** (Save/Update/Delete) — NHibernate Session 操作內聚於實體。
- BLL (Business Logic):**純業務邏輯**,調用實體方法完成持久化,**不負責前台數據組裝**。
- DataViewer (Data Access for UI):從原 BLL **剝離出來**,專責**讀取數據供前台顯示** (分頁、排序、多表連接、報表)。
- **不使用 HQL** → 直接寫 SQL / 預存過程 / 視圖,效能可控、無學習成本、可優化。
- **操作視圖而非表** → 結構變更只改視圖,DataViewer 無感。
- 表示層:調用 BLL 執行業務,調用 DataViewer 獲取顯示數據。
核心優勢
| 維度 | 動軟三層 | NHibernate 三層 |
| 新增查詢 | 三層同步修改 | DataViewer 單點新增 SQL |
| 表結構變更 | 重生成/逐層改 | 視圖隔離,Model 映射微調 |
| 跨表業務 | BLL 強行耦合 | Model 關聯導航 + BLL 編排 |
| 數據訪問方式 | 存儲過程/參數化 SQL | Model: NHibernate Session; DataViewer: 原生 SQL |
| 前台數據組裝 | BLL 混雜 | DataViewer 專責 |
落地關鍵決策
- Model 封裝 Save/Update/Delete:實體持有 `ISession` 引用 (或靜態 `SessionFactory`),`entity.Save()` 內部 `session.SaveOrUpdate(this)` — 讓業務代碼 `order.Save()` 自然流暢。
- BLL 純粹業務規則:如 `OrderService.PlaceOrder()` 驗證庫存、計算折扣、調用 `order.Save()`、`inventory.Deduct()` — 無 SQL、無 DataTable。
- DataViewer 只讀優化:`GetOrderList(page, size, filter)` → 直連 SQL/視圖 → 返回 `List` / `DataTable` — 不開啟 NHibernate Session,避免延遲加載、N+1 問題。
- 視圖作為契約:`v_OrderList` 定義前台所需欄位,Schema 變更只改視圖,雙方解耦。
遷移路徑建議
- 引入 NHibernate,建立實體映射 (`.hbm.xml` / Fluent / Attribute)。
- 將現有 DAL/BLL 邏輯重構為 Model 領域方法 + BLL 業務服務。
- 識別「純讀取/報表/複雜查詢」類 BLL 方法,剝離為 DataViewer。
- 建立資料庫視圖對應 DataViewer 查詢。
- 逐模組切換,舊 DAL 併行運行至完全替換。
NHibernate 三層 = **領域模型持久化** + **純業務編排** + **只讀查詢分離** — 符合 DDD 分層架構精神,是從「表驅動」邁向「領域驅動」的關鍵一步。