Ayant deux classes:
public class Parent
{
public int Id { get; set; }
public int ChildId { get; set; }
}
public class Child { ... }
Lors de l'affectation ChildId
à, Parent
dois-je d'abord vérifier s'il existe dans la base de données ou attendre que la base de données lève une exception?
Par exemple (en utilisant Entity Framework Core):
REMARQUE: ces types de vérifications sont TOUS SUR INTERNET, même sur les documents officiels de Microsoft: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using- mvc / traitement-concurrence-avec-l'entité-structure-dans-un-asp-net-mvc-application # modifier-le-contrôleur-département, mais il existe une gestion supplémentaire des exceptions pourSaveChanges
Notez également que l'objectif principal de cette vérification était de renvoyer un message convivial et un statut HTTP connu à l'utilisateur de l'API et de ne pas ignorer complètement les exceptions de base de données. Et la seule exception à être levée est à l'intérieur SaveChanges
ou SaveChangesAsync
appeler ... donc il n'y aura pas d'exception lorsque vous appelez FindAsync
ou Any
. Donc, si l'enfant existe mais a été supprimé avant, SaveChangesAsync
une exception d'accès simultané sera levée.
J'ai fait cela parce que l' foreign key violation
exception sera beaucoup plus difficile à formater pour afficher "L'enfant avec l'id {parent.ChildId} est introuvable."
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;
}
contre:
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;
}
Le deuxième exemple dans Postgres va générer une 23503 foreign_key_violation
erreur: https://www.postgresql.org/docs/9.4/static/errcodes-appendix.html
L'inconvénient de la gestion des exceptions de cette manière dans ORM comme EF est que cela ne fonctionnera qu'avec un système de base de données spécifique. Si vous avez toujours voulu passer au serveur SQL ou à quelque chose d'autre, cela ne fonctionnera plus car le code d'erreur sera modifié.
Ne pas formater correctement l'exception pour l'utilisateur final pourrait exposer des choses que vous ne voulez que les développeurs voient.
En relation:
https://stackoverflow.com/questions/308905/should-there-be-a-transaction-for-read-queries
Child with id {parent.ChildId} could not be found.
. Et le formatage "violation de clé étrangère" est selon moi pire dans ce cas.