Zwei Klassen haben:
public class Parent
{
public int Id { get; set; }
public int ChildId { get; set; }
}
public class Child { ... }
Soll ich beim Zuweisen ChildId
zu Parent
zuerst überprüfen, ob es in der Datenbank vorhanden ist, oder warten, bis die Datenbank eine Ausnahme auslöst?
Zum Beispiel (mit Entity Framework Core):
HINWEIS: Diese Überprüfungsarten sind auch in den offiziellen Microsoft-Dokumenten im gesamten Internet verfügbar: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using- mvc / handling-concurrency-with-the-entity-framework-in-einem-asp-net-mvc-application # Abteilung-Controller modifizieren, aber es gibt zusätzliche Ausnahmebehandlung fürSaveChanges
Beachten Sie außerdem, dass die Hauptabsicht dieser Überprüfung darin bestand, dem Benutzer der API eine angezeigte Nachricht und einen bekannten HTTP-Status zurückzugeben und Datenbankausnahmen nicht vollständig zu ignorieren. Und der einzige Ort, an dem eine Ausnahme ausgelöst wird, ist inside SaveChanges
oder SaveChangesAsync
call ... also gibt es keine Ausnahme, wenn Sie FindAsync
oder anrufen Any
. Wenn also ein untergeordnetes Element vorhanden ist, das jedoch zuvor gelöscht wurde, SaveChangesAsync
wird eine Nebenläufigkeitsausnahme ausgelöst.
Dies geschah aufgrund der Tatsache, dass foreign key violation
die Formatierung der Ausnahme für die Anzeige "Kind mit der ID {parent.ChildId} konnte nicht gefunden werden" erheblich schwieriger sein wird.
public async Task<ActionResult<Parent>> CreateParent(Parent parent)
{
// is this code redundant?
// NOTE: its probably better to use Any isntead of FindAsync because FindAsync selects *, and Any selects 1
var child = await _db.Children.FindAsync(parent.ChildId);
if (child == null)
return NotFound($"Child with id {parent.ChildId} could not be found.");
_db.Parents.Add(parent);
await _db.SaveChangesAsync();
return parent;
}
gegen:
public async Task<ActionResult<Parent>> CreateParent(Parent parent)
{
_db.Parents.Add(parent);
await _db.SaveChangesAsync(); // handle exception somewhere globally when child with the specified id doesn't exist...
return parent;
}
Das zweite Beispiel in Postgres löst einen 23503 foreign_key_violation
Fehler aus: https://www.postgresql.org/docs/9.4/static/errcodes-appendix.html
Der Nachteil der Behandlung von Ausnahmen auf diese Weise in ORM wie EF ist, dass sie nur mit einem bestimmten Datenbank-Backend funktionieren. Wenn Sie jemals zu SQL Server oder etwas anderem wechseln wollten, funktioniert dies nicht mehr, da sich der Fehlercode ändert.
Wenn die Ausnahme für den Endbenutzer nicht richtig formatiert wird, können einige Dinge angezeigt werden, die nur von Entwicklern angezeigt werden sollen.
Verbunden:
https://stackoverflow.com/questions/308905/sollte-es-ein-Transaktion-für-Leseanfragen sein
Child with id {parent.ChildId} could not be found.
. Und die Formatierung "Fremdschlüsselverletzung" finde ich in diesem Fall schlimmer.