Ayant deux classes:
public class Parent
{
public int Id { get; set; }
public int ChildId { get; set; }
}
public class Child { ... }
Lors de l'affectation ChildIdà, Parentdois-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 SaveChangesou SaveChangesAsyncappeler ... donc il n'y aura pas d'exception lorsque vous appelez FindAsyncou Any. Donc, si l'enfant existe mais a été supprimé avant, SaveChangesAsyncune exception d'accès simultané sera levée.
J'ai fait cela parce que l' foreign key violationexception 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_violationerreur: 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.