Frage

Ich hatte immer das Gefühl, dass Ausnahmen erwartet auf einer regelmäßigen Basis geworfen zu werden und sie als Ablauflogik verwendet eine schlechte Sache war. Ausnahmen fühlen, wie sie sollten, na ja, die " Ausnahme " sein. Wenn Sie erwarten, und eine Ausnahme planen, dass scheint darauf hinzudeuten, dass Ihr Code Refactoring werden soll, zumindest in .NET ...
Jedoch. Eine aktuelle Szenario gab mir denken. Ich gepostet auf Msdn eine Weile her, aber ich würde gerne mehr Diskussion darüber erzeugen, und dies ist der perfekte Ort!

Also, sagen Sie eine Datenbanktabelle haben, die einen Fremdschlüssel für mehrere andere Tabellen hat (in dem Fall, dass ursprünglich die Debatte aufgefordert, gab es vier Fremdschlüssel auf sie zeigen). Sie möchten dem Benutzer ermöglichen, zu löschen, aber nur, wenn es keine Fremdschlüssel-Referenzen; Sie wollen nicht Kaskade löschen.
Ich normalerweise tun, nur einen Scheck, um zu sehen, ob es irgendwelche Referenzen sind, und wenn es, ich informiere die Benutzer stattdessen die Lösch zu tun. Es ist sehr einfach und entspannend, dass in LINQ zu schreiben, wie verknüpften Tabellen-Mitglieder auf dem Objekt sind, so Section.Projects und Section.Categories und et cetera ist schön mit Intellisense und alles zu geben ...
Aber die Tatsache ist, dass LINQ dann getroffen hat möglicherweise alle vier Tabellen, um zu sehen, ob es irgendwelche Ergebniszeilen sind zu diesem Eintrag zeigen und die Datenbank schlagen ist offensichtlich immer eine relativ teuere Operation.

Die Leitung dieses Projekt hat mich gebeten, es zu ändern, um nur einen SqlException mit einem Code von 547 (Fremdschlüssel) zu fangen und behandelt es so.

Ich war ...
beständig .

Aber in diesem Fall, ist es wahrscheinlich viel effizienter die Ausnahme bezogenen Gemeinkosten zu schlucken als die 4 Tabelle trifft zu schlucken ... Vor allem, da wir den Scheck in jedem Fall zu tun haben, aber wir sind die Ausnahme im Fall verschont wenn es keine Kinder gibt ...
Plus die Datenbank wirklich sollte der Verantwortliche für den Umgang mit der referentiellen Integrität sein, das ist seine Aufgabe und es tut es gut ...
So gewannen sie und ich änderte es.

Auf einer bestimmten Ebene immer noch fühlt es falsch mir aber.

Was denkt ihr über erwartete und beabsichtigte Behandlung von Ausnahmen? Ist es in Ordnung, wenn es aussieht wie es als Überprüfung vorher effizienter sein wird? Ist es verwirrend für den nächsten Entwickler bei Ihrem Code suchen oder weniger verwirrend? Ist es sicherer, da die Datenbank über neue Fremdschlüssel-Constraints wissen könnte, dass der Entwickler nicht einen Scheck hinzufügen könnte denken? Oder ist es eine Frage der Perspektive, was genau denken Sie am beste Praxis ist?

War es hilfreich?

Lösung

Wow,

Als erstes können Sie die Frage bitte ein wenig nach unten destillieren, während es schön war gut zu lesen dachte und erklärte Frage, das war ziemlich viel zu verdauen.

Die kurze Antwort lautet „ja“, aber es kann abhängig sein.

  • Wir haben einige Anwendungen, bei denen wir viele Geschäftslogik haben in den SQL-Abfragen gebunden (nicht mein Design Gov!). Wenn dies ist, wie es strukturiert ist, kann das Management schwierig sein, vom Gegenteil zu überzeugen, da es „schon funktioniert“.
  • In dieser Situation ist es wirklich eine große Sache machen? Da es immer noch eine Reise über den Draht und zurück. Hat der Server viel zu tun, bevor er merkt, dass es nicht fortgesetzt werden kann (i.e.if es eine Folge von Transaktionen, den Ort, um Ihre Maßnahmen zu ergreifen, ist es dann mehr als die Hälfte Weg fällt durch, Zeit zu verschwenden?).
  • Ist es sinnvoll die Prüfung in der Benutzeroberfläche als Erstes zu tun? Ist es mit Ihrer Anwendung helfen? Wenn es einen schönen User Experience? (D Ich habe Fälle gesehen, wo man mehrere Schritte in einem Assistenten Schritt für Schritt durch, es beginnt, dann umfällt, wenn es alle Informationen hatte es gebraucht nach dem Schritt umfallen 1).
  • Ist Gleichzeitigkeit ein Thema? Ist es möglich, dass der Datensatz entfernt werden kann / bearbeitet oder was auch immer, bevor Sie verpflichten erfolgt (wie im klassischen File.Exists boo-boo).

Meiner Meinung nach:

ich tun würde, beide . Wenn ich schnell scheitern und eine bessere Benutzererfahrung bieten, groß. Alle erwarteten SQL (oder andere) Ausnahmen sollten wieder in geeigneter Weise sowieso gefangen und gefüttert werden zu werden.

Ich weiß, dass es einen Konsens ist, dass Ausnahmen sollten nicht für andere als außergewöhnliche Umstände verwendet werden, aber denken Sie daran, wir überqueren Anwendungsgrenzen hier erwarten nichts . Wie ich schon sagte, ist dies wie der File.Exists, es hat keinen Sinn, es kann gelöscht werden, bevor Sie es trotzdem zugreifen.

Andere Tipps

Ihre Führung ist absolut richtig. Ausnahmen sind nicht nur einmal in einer blauen Mond Situationen, aber speziell für andere als die erwarteten Ergebnisse berichten.

In diesem Fall wird die Fremdschlüsselprüfung würde immer noch stattfinden, und Ausnahmen sind der Mechanismus, mit dem Sie benachrichtigt werden können.

Was Sie nicht tun sollten, ist zu fangen und zu unterdrücken Ausnahmen mit einer Decke catchall Aussage. feinkörnige Ausnahmebehandlung zu tun, ist speziell, warum Ausnahmen in erster Linie entworfen wurden.

Ich glaube, Sie haben Recht, Ausnahmen sollten nur verwendet werden behandeln unerwartet Ergebnisse, hier gibt es eine Ausnahme verwenden, der mit einem möglicherweise erwartete Ergebnis zu behandeln, sollten Sie mit diesem Fall befassen explizit, aber immer noch fangen die Ausnahme einen möglichen Fehler zu zeigen.

Es sei denn, dies ist der Weg dieser Fall alle den ganzen Code behandelt wird, würde ich mit Ihnen Seite. Das Performance-Problem sollte nur gebracht werden, wenn es tatsächlich ein Problem ist, das heißt es von der Größe dieser Tabellen und der Anzahl der diese Funktion verwendet wird abhängen würde.

Nizza Frage. Allerdings finde ich die Antworten ... scary!
Eine Ausnahme ist eine Art von GOTO.
Ich mag es nicht Ausnahmen auf diese Weise verwenden, weil das zu Spaghetti-Code führt.
So einfach ist das.

Es ist nichts falsch mit dem, was Sie tun. Ausnahmen sind nicht nessesarily „außergewöhnlich“. Sie existieren, damit Objekte aufrufe feinkörnige Fehlerbehandlung auf ihren Bedürfnisse aus.

die spezifischen SqlException Fangen ist das Richtige zu tun. Dies ist der Mechanismus, mit der SQL Server die Fremdschlüsselbedingung in Verbindung steht. Auch wenn Sie eine andere Nutzung des Ausnahmemechanismus begünstigen könnten, das ist, wie SQL Server es funktioniert.

Auch während der Prüfung an den vier Tabellen, könnte ein anderer Benutzer einen verknüpften Datensatz hinzufügen, vor dem Check, nachdem Sie abgeschlossen ist, aber die Tabelle lesen.

Ich würde empfehlen, eine gespeicherte Prozedur aufrufen, die es überprüft, ob irgendwelche Abhängigkeiten sind, dann löscht, wenn es nicht. Auf diese Weise wird die Prüfung für Integrität getan.

Natürlich würden Sie wahrscheinlich eine andere gespeicherte Prozedur für Singleton Löschungen vs. Batch löschen wollen ... Der Ansatz für Kinder Zeilen aussehen löschen könnte und eine Reihe von Datensätzen zurückzukehren, die für einen Großteil nicht förderfähig waren löschen (hatte Kind Zeilen).

Ich mag keine Ausnahmen überall in einem Programm zu sehen, aber in diesem Fall würde ich den Ausnahme-Mechanismus verwenden.

Auch wenn Sie in LINQ zu testen, erhalten Sie die Ausnahme im Falle fangen müssen jemand ein Kind Datensatz einfügt, während Sie Integrität mit LINQ zu testen sind. Da Sie die Ausnahme sowieso überprüfen, warum Sie den Code duplizieren?

Ein weiterer Punkt ist, dass diese Art von „short range“ Ausnahme nicht Wartungsprobleme verursacht, noch macht es Ihr Programm schwieriger zu lesen. Sie werden den Versuch haben, den SQL-Aufruf zu löschen und den Fang, das alles innerhalb von 10 Zeilen Code, zusammen. Die Absicht ist offensichtlich.

Nicht wie eine Ausnahme zu werfen, die gefangen werden soll 5 Verfahren oberen im Stapel nennen, mit den Problemen sicher zu sein, dass alle Objekte zwischendurch versorgt (befreit) wurde korrekt.

Ausnahmen sind nicht immer eine magische Antwort, aber ich würde nicht das Gefühl, falsch, sie in dieser Situation zu verwenden.

Meine zwei Cent,

Yves

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top