简体   繁体   中英

Catching broken database contraints in C# - Best Practice

Say I have an SQL table that has a unique key (or other) constraint on one of the columns.

Then, I have an application (lets go ASP.NET MVC) that allows a user to edit this column.

When the user attempts to save, and the constraint is/will be broken, I need show a user-friendly error message to the user. As such, which of the following is better practice?

  1. Have the application query the database to ensure the constraints are not broken, and then insert/update the row (results in two queries to the db)

    OR

  2. Immediately attempt to perform the insert/update, and catch the SqlException should the constraint be broken. I like this, because of only one trip to the db, however how should you then extract which index/constraint was broken and affix the appropriate message? (apart from inspecting Exception.Message?)

1 is the better all-around solution. Db calls are not the only expensive operation, exceptions are costly too. You should really only let your db throw an exception when something goes wrong due to your code, not a user action.

For example, you might later want to install Elmah and get exceptions logged and/or mailed to you. Elmah would log/mail such an exception unless you explicitly told it not to.

Plus like you said, exceptions don't always have the most businessy information to communicate to users (especially SQL exceptions, which are SQL-specific). You have these unique and other constraints for a reason. For those reasons, validate the information before trying to store it.

Take twitter, gmail, etc. When you go to get a username, the application first checks to see if it is taken. These are uniqueness constraints at the application level, which may or may not ultimately be realized as SQL constraints. Since it is your application that faces the user, you should not try to communicate to them by translating from SQL to English.

The problem with option 1 is that it requires the application to have separate distinct knowledge of what the constraints are, which conflicts with a DRY principle, and could lead to problems later when the database constraint gets changed, and the application is not updated - a tight coupling between the data logic, and the application. Also, there is no guarantee of the constraint checks that were performed are still valid at the subsequent pont when you then attempt the update.

This doesn't preclude augmenting your application with some UI layer validation to aid the user before the commit is attempted.

So if that is discarded we are left with option 2, and some translation is necessary somewhere in the application. Where you put that translation and that logic, whether in a Stored Procedurce or a Business Logic layer, is up to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM