2012-07-19 20 views
2

假設我有一個SQL表,其中一列具有唯一鍵(或其他)約束。在C#中捕獲破損的數據庫約束 - 最佳實踐

然後,我有一個應用程序(讓ASP.NET MVC),允許用戶編輯此列。

當用戶嘗試保存,並且約束被/將被破壞時,我需要向用戶顯示一個用戶友好的錯誤消息。因此,以下哪一種更好?

  1. 有應用程序查詢數據庫,以確保限制未破,然後插入/更新行(在兩次查詢結果給DB)

    OR

  2. 立即嘗試執行插入/更新,並在約束被破壞時捕獲SqlException。我喜歡這個,因爲只有一次去分貝,但是你應該如何提取哪個索引/約束被破壞並且貼上適當的消息? (除了檢查Exception.Message?)

回答

1

1是更好的全面解決方案。 Db電話不是唯一昂貴的操作,例外也是昂貴的。如果由於代碼而導致某些錯誤,而不是用戶操作,則應該只讓數據庫拋出異常。

例如,您稍後可能想要安裝Elmah並獲取記錄日誌和/或將郵件發送給您。除非你明確告訴它不要,否則Elmah會記錄/發送這樣一個異常。如你所說,異常並不總是有最多的商業信息與用戶溝通(特別是SQL異常,這是SQL特定的)。出於某種原因你有這些獨特的和其他的限制。出於這些原因,在嘗試存儲信息之前驗證信息。

帶上twitter,gmail等。當你去獲取用戶名時,應用程序首先檢查它是否被採用。這些是應用程序級別的唯一性約束,可能最終也可能不會實現爲SQL約束。由於它是面向用戶的應用程序,因此您不應該嘗試通過從SQL轉換爲英語來與他們進行通信。

+0

同意 - 特別是因爲您可以在輸入代碼時在前端執行一些ajax類型驗證,從表單提交中保存用戶。 – Paddy 2012-07-19 07:53:23

+2

這不會使你免於做2。事實上,你已經檢查過你的模型在T時刻是否有效,並不意味着當你嘗試實際保存它時,這個模型在T + 1時刻是有效的。結論是,你至少應該做2.如果你想提供更好的用戶反饋,你也可以實現1.使用AJAX或其他。 – 2012-07-19 08:02:00

+0

@Paddy是的,這可能是事實上的方式與用戶溝通有關服務器端應用程序的限制。您不希望在每次擊鍵時拋出異常,特別是如果您的數據具有二級緩存。 – danludwig 2012-07-19 08:02:05

0

選項1的問題在於它需要應用程序對DRY原則有衝突的約束有單獨的明確知識,並且在數據庫約束被更改時可能會導致問題,並且應用程序是未更新 - 數據邏輯與應用程序之間的緊密耦合。此外,當您嘗試更新時,不能保證在隨後的pont中執行的約束檢查仍然有效。

這並不排除用一些UI層驗證來增強您的應用程序以在嘗試提交之前幫助用戶。

因此,如果這被丟棄,我們留下選項2,並且在應用程序的某處需要一些翻譯。無論是在「存儲過程」還是「業務邏輯」層,放置該翻譯和邏輯的位置由您決定。