Entity Framework: comment gérer correctement les exceptions dues à des contraintes SQL

constraints entity-framework sql sql-server unique-constraint

Question

J'utilise Entity Framework pour accéder à mes données SQL. J'ai quelques contraintes dans le schéma de base de données et je me demande comment gérer les exceptions causées par ces contraintes.

A titre d'exemple, j'obtiens l'exception suivante dans le cas où deux utilisateurs essaient d'ajouter une entité (presque) identique à la base de données simultanément.

System.Data.UpdateException
"An error occurred while updating the entries. See the InnerException for details."

(inner exception) System.Data.SqlClient.SqlException
"Violation of UNIQUE KEY constraint 'Unique_GiftId'. Cannot insert duplicate key in object 'dbo.Donations'.\r\nThe statement has been terminated."

Comment attraper correctement cette exception spécifique?

Solution sale:

    catch (UpdateException ex)
    {
        SqlException innerException = ex.InnerException as SqlException;
        if (innerException != null && innerException.Message.StartsWith("Violation of UNIQUE KEY constraint 'Unique_GiftId'"))
        {
            // handle exception here..
        }
        else
        {
            throw;
        }
    }

Bien que cette approche fonctionne, elle présente certains inconvénients:

  • Aucun type de sécurité: le code dépend du message d'exception qui contient le nom de la colonne unique.
  • Dépendance à l'égard des classes SqlCLient (abstraction interrompue)

Connaissez-vous une meilleure solution pour cela? Merci pour tous vos commentaires ..

Remarque: Je ne souhaite pas coder les contraintes manuellement dans la couche d'application, je souhaite les avoir dans la base de données.

Réponse acceptée

Vous devriez pouvoir intercepter le numéro d'erreur SQL (qui est SqlException.Number )

Dans ce cas, il s’agit du 2627, qui est identique depuis toujours pour SQL Server.

Si vous voulez une abstraction, vous aurez toujours une dépendance vis-à-vis du moteur de base de données, car chacun lancera des numéros d'exception et des messages différents.


Réponse populaire

Une solution consiste à inspecter la propriété Errors de l'exception SqlException interne. La classe SqlError a une propriété Number qui identifie l'erreur exacte. Consultez la table master.dbo.sysmessages pour obtenir une liste de tous les codes d'erreur.

Bien sûr, cela vous lie toujours à SQL Server. Je ne connais pas d'autre moyen de résumer ce problème que de lancer votre propre "analyseur d'exception EF".



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow