繼視圖應用後,本系列將用三篇幅深入講解 NHibernate 中存儲過程的完整應用流程。所有內容源自實戰經驗,涵蓋錯誤排查、存儲過程修改、與原生操作差異對比,非官方權威文檔,請開發者酌情參考。
為專注 NHibernate 整合而非 T-SQL 編寫,採用 MyGeneration 代碼生成工具為 Customer 表生成增刪改存儲過程。
Script Insert/Update/Delete Procedures for SQL Server 模板Customer,點擊 OKsql_procs_Customer.sql,在 SSMS 中執行腳本NHibernateSample 下出現三個存儲過程——CustomerDelete、CustomerInsert、CustomerUpdate測試代碼沿用系列第 6 篇事務與第 5 篇 CRUD 操作,無需修改。
DELETE FROM Customer WHERE CustomerId = @p0 AND Version = @p1; @p0 = '7', @p1 = '1'
包含版本控制欄位 Version,實現樂觀並發。
修改 Customer.hbm.xml,在 <class> 下添加:
<sql-delete>exec CustomerDelete ?</sql-delete>
對應存儲過程單一 @CustomerId 參數。
執行報錯 StaleObjectStateException,修改存儲過程註釋 SET NOCOUNT ON:
ALTER PROCEDURE [dbo].[CustomerDelete]
(@CustomerId int)
AS
-- SET NOCOUNT ON
DELETE FROM [Customer] WHERE [CustomerId] = @CustomerId
RETURN @@Error
執行成功但發現 NHibernate 生成 SQL 多出 @p1 參數:
exec CustomerDelete @p0; @p0 = '6', @p1 = '1'
存儲過程未處理版本控制,導致邏輯不一致。
ALTER PROCEDURE [dbo].[CustomerDelete]
(@CustomerId int, @Version int)
AS
DELETE FROM [Customer] WHERE [CustomerId] = @CustomerId AND [Version] = @Version
RETURN @@Error
修改映射文件增加第二個參數:
<sql-delete>exec CustomerDelete ?,?</sql-delete>
測試通過,生成 SQL 與原生完全一致:
exec CustomerDelete @p0,@p1; @p0 = '8', @p1 = '1'
<sql-delete>DELETE FROM [Customer] WHERE [CustomerId] = ? AND [Version] =?</sql-delete>
本文完成 MyGeneration 生成存儲過程與刪除操作整合。下篇將繼續講解新增、更新、查詢操作的存儲過程應用細節。