2009-05-28 16 views
0

Worauf sollten Sie bei der Fehlerbehandlung achten, wenn Sie mit der Datenzugriffsebene arbeiten? Zum Beispiel, nehmen wir an, ich habe diese Funktion ..Korrekte Fehlerbehandlungspraktiken für die Datenschicht

Public Function UserExists(ByVal userName As String) As DataTable 
     Dim dt As Object = Nothing 
     Dim arSqlParameters(0) As SqlParameter 
     arSqlParameters(0) = New SqlParameter("@UserName", SqlDbType.NVarChar, 50) 
     arSqlParameters(0).value = userName 
     dt = ABC.APP.DAL.DALHelper.ExecuteDatatable(ConnectionString, CommandType.StoredProcedure, "dbo.aspnet_sprGetUserByUsername", arSqlParameters) 
     Return dt 
    End Function 

Das ist wie sehr faul und unsichere Codierung scheint. Wie würden Sie sicherstellen, dass Ihr Code in einer solchen Situation elegant mit etwas Unerwartetem zurechtkommt?

Ich bin neu bei vb.net und die App, an der ich arbeite, hat keine Fehlerbehandlung, daher dachte ich, dies wäre der beste Ort, um Rat zu suchen. Vielen Dank im Voraus :)

Antwort

1

Nicht sicher, warum Sie dt nicht als Datentabelle deklarieren - was ist die Motivation für "dim dt as object = nothing"?

Wirklich die einzige Linie, die vernünftigerweise scheitern kann, ist der Aufruf "dt = ABC.APP.DAL ....".

In dieser Linie könnten Sie ein paar Fehler haben:

  • Die gespeicherte Prozedur oder Parameter Namen falsch sind.Dies sollte zur Entwurfszeit gefangen wird (nicht durch ein eingebauten Mechanismus überprüft, aber das erste Mal, dass Sie versuchen, den Code auszuführen)
  • Ein Fehler tritt in den gespeicherten Verfahren. Sprocs verwenden den verzögerten Namen Auflösung, die zur Laufzeit Fehler führen kann, wenn (zum Beispiel) Objekte nicht zu der Zeit existieren, dass der Sproc aufgerufen wird. Auch dies ist die meisten wahrscheinlich, es ist Kopf im Test.
  • Ein Deadlock. In diesem Fall sollten Sie fangen und den Stapel erneut einreichen. Here ist ein Intro und Satz von Links auf die Behandlung von SQL-Fehlern in der Anwendung Code.
  • Ein übergebener Parameter ist ungültig (zu lang, falscher Datentyp, usw.). Dies sollte überprüft werden vor Sie rufen den Sproc.
+0

In Bezug auf das Verständnis der Motivation hinter "dim dt als Objekt = nichts" zu verstehen, stimme ich zu. Ich bin so spät in den Entwicklungszyklus gekommen, und das ist bereits geschriebener Code von einem früheren Entwickler. – Chris

1

Meinungen sind wahrscheinlich wild auf ein Thema wie dieses variieren, aber hier ist mein nehmen. Versuchen Sie nur, mit den Ausnahmen umzugehen, die Sie in diesem Bereich haben. Das ist eine vage Aussage, aber was ich meine ist, hat der Benutzer eine Zeichenfolge mit mehr Zeichen übergeben als die Spalte in der Datenbank. Oder haben sie eine andere Geschäftsregel verletzt?

Ich würde nicht fangen Fehler hier, die implizieren, die Datenbank ist down. So weit in den Code, Sie fangen Fehler, mit denen Sie umgehen können, und Ihre App benötigt ihre Datenbank. Deklarieren Sie einen globaleren Ausnahmebehandler, der das Problem protokolliert, jemanden benachrichtigt, was auch immer ... und dem Benutzer einen "anmutigen" Exit präsentiert.

Ich sehe keinen Wert darin, in jeder Methode ein Problem mit der Datenbank zu fangen. Sie wiederholen nur Code für ein Szenario, das einen Teil Ihres Datenlayers bombardieren könnte. Wenn Sie jedoch vorhaben, db-Fehler (oder andere allgemeine Fehler) in dieser Methode abzufangen, setzen Sie zumindest die interne Ausnahme auf die abgefangene Ausnahme, wenn Sie eine neue Ausnahme auslösen. Oder besser, logg was du willst und dann nur "werfen", nicht "werfen". Es behält den ursprünglichen Stack-Trace.

Auch hier werden Sie viele verschiedene Gedanken dazu bekommen, und es gibt keine klaren Richtig und Falsch, nur Vorlieben.

1

ein Blick ins Innere Der Code der Open Source ORM-Lösungen (Subsonic, nHibernate) wird Ihnen helfen.

Durch meine begrenzten Kenntnisse denke ich, dass Fehler in Bezug auf Verbindungen, Verbindungstimeouts usw. als solche weitergegeben werden sollten, weil DAL nicht viel dagegen tun kann. Fehler im Zusammenhang mit den Validierungen (wie Feldlängen, Datentypen) usw. sollten mit entsprechenden Details zurückgegeben werden. Sie können Validierungsmethoden bereitstellen (Subsonic enthält diese), die die Feldwerte validieren und die entsprechenden Fehlerdetails zurückgeben.

0

Ich habe viel darüber nachgedacht. Eine Menge hängt von der jeweiligen Datenbank ab. Abhängig davon, ob Sie SQL2000 oder SQL2005 + verwenden, werden Sie entweder Rückkehrcodes, RAISERROR oder TRY-CATCH in der gespeicherten Prozedur ausführen.

RAISERROR liefert vorzugsweise Codes, da Entwickler, die die gespeicherte Prozedur verwenden, mehr Informationen erhalten. Optimal würden Sie Zahlen 50000 und höher auswählen und die entsprechenden Nachrichten registrieren, aber das ist eine Menge Arbeit nur zu kommunizieren, was im Text des RAISERROR-Aufrufs kommuniziert werden kann

Der Rückkehrcode ist nicht unterbrechbar, ohne den Quellcode zu lesen der gespeicherten Prozedur. Ein Rückgabewert von 0 ist möglicherweise Erfolg, Fehler, 0 Zeilen betroffen, der gerade generierte Primärschlüssel, oder dass kein Rückgabecode abhängig von den Launen des Schreibprogramms der gespeicherten Prozedur an diesem Tag gesetzt wurde. Darüber hinaus gibt ADO.NET Zeilenanzahl von ExecuteNonQuery zurück, so dass es einigen Entwicklern schwer fällt, den Rückkehrcode schnell zu ermitteln.

Ad-hoc-Lösungen sind auch schlecht, z.

IF @@Error>0 
    SELECT 'Something bad happened' 

Wenn Sie CLR gespeicherte Prozeduren verwenden können, kommt die C# -Stilfehlerbehandlung ins Spiel.

Fügen Sie also RAISERROR zu Ihren gespeicherten Prozeduren hinzu, fangen Sie dann SqlException ab, melden Sie dem Benutzer alles, was wirklich ein Benutzerdateneintrag ist. Validieren Sie alles, wenn ein Entwickler die API missbraucht und versuchen Sie es vielleicht erneut Ausführungstimeouts

IF @Foo =42 
     BEGIN 
      RAISERROR ('Paramater @foo can''t be 42', 
       16, -- Severity = Misc. User Error. 
       1 -- State. == ad hoc way of finding line of code that raised error 
       ) ; 
      RETURN -1; --Just because some developers are looking for this by habit 
     END 
+1

Die Verwendung von RAISERROR mit Zahlen über 50000 hat auch ein anderes Problem, da die benutzerdefinierten Fehlercodes serverweit sind (zumindest ab 2005 muss ich das Jahr 2008 überprüfen). Es ist geringfügig, aber ärgerlich, besonders wenn Sie Ihre Datenbank zwischen Servern verschieben und andere Datenbanken verwenden, die auch ihre eigenen benutzerdefinierten Fehler verwenden möchten. –

Verwandte Themen