17

Ich verwende Entity Framework für den Zugriff auf meine SQL-Daten. Ich habe einige Beschränkungen im Datenbankschema und ich frage mich, wie man Ausnahmen behandelt, die durch diese Beschränkungen verursacht werden.Entity Framework: Wie umgehen Sie Ausnahmen, die aufgrund von SQL-Einschränkungen auftreten

Als Beispiel bekomme ich die folgende Ausnahme in einem Fall, in dem zwei Benutzer versuchen, eine (fast) identische Entität zu der DB gleichzeitig hinzuzufügen.

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." 

Wie kann ich diese spezifische Ausnahme richtig erfassen?

Schmutzige Lösung:

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; 
     } 
    } 

Jetzt, während dieser Ansatz funktioniert, hat es einige Nachteile:

  • Keine Typsicherheit: Der Code auf der Ausnahmemeldung abhängig ist, die den Namen des enthält eindeutige Spalte.
  • Abhängigkeit von den SQLClient Klassen (gebrochene Abstraktion)

Kennen Sie eine bessere Lösung? Vielen Dank für alle Feedback ..

Hinweis: ich nicht die Einschränkungen manuell innerhalb der Anwendungsschicht codieren will, ich will, dass sie in der DB haben.

Antwort

17

sollten Sie in der Lage sein, um die SQL-Fehlernummer zu stoppen

In diesem Fall (die SqlException.Number ist) es 2627 ist, die gleich für immer für SQL Server wurde.

Wenn Sie Abstraktion wünschen, dann haben Sie immer eine Abhängigkeit von der Datenbank-Engine, weil jede unterschiedliche Ausnahme-Nummern und Nachrichten auslösen wird.

+0

Okay, aber selbst wenn ich diese ID verwende, muss ich die Ausnahmebedingung für den Spaltennamen parsen. – driAn

+0

@driAn: richtig. SQL hat auch keinen nativen Mechanismus, um zu einer Einschränkung oder Spalte zu bohren, was bedeutet, dass es keine API oder dergleichen gibt, um sie zu lesen. – gbn

2

Eine Möglichkeit besteht darin, die Errors property der inneren SqlException zu überprüfen. Die SqlError-Klasse hat eine , die den genauen Fehler identifiziert. Eine Liste aller Fehlercodes finden Sie in der Tabelle master.dbo.sysmessages.

Natürlich verbindet Sie dies immer noch mit SQL Server. Ich bin mir nicht bewusst, dass ich dies abstrahieren kann, außer dass Sie Ihren eigenen "EF-Ausnahmeanalysator" rollen.

0

Dieses Szenario sollte nicht auftreten, da der Schlüssel niemals explizit zugewiesen werden sollte, wenn EF verwendet wird. vielmehr erlaubt der Kontext, einen passenden zuzuweisen. Wenn es sich um ein Problem mit Parallelität handelt, sollten Sie das Update in einem Transaktionsbereich durchführen.

Wenn Sie eine UpdateException haben, können Sie das Update erneut versuchen. Sie können dies sicher in einem Transaktionsbereich tun und den Umfang nur vervollständigen, wenn das Update gründlich ausgeführt wird. In diesem Szenario ist die Wahrscheinlichkeit, dass das Update das nächste Mal durchläuft, größer als beim ersten Mal.

Verwandte Themen