Détails des erreurs SaveChanges Entity Framework

c# entity-framework

Question

Lorsque vous enregistrez des modifications avec SaveChanges sur un contexte de données, existe-t-il un moyen de déterminer quelle entité provoque une erreur? Par exemple, parfois, j'oublie d'attribuer une date à un champ de date non nullable et d'obtenir l'erreur "Plage de dates non valide", mais je ne reçois aucune information sur l'entité ou le champ provoqués par cette erreur (je peux généralement la localiser par parcourir minutieusement tous mes objets, mais cela prend beaucoup de temps). La trace de pile est plutôt inutile car elle me montre seulement une erreur lors de l'appel SaveChanges sans aucune information supplémentaire quant à l'endroit exact où cela s'est produit.

Notez que je ne cherche pas à résoudre un problème particulier que j'ai maintenant. J'aimerais simplement savoir en général s'il existe un moyen de déterminer quelle entité / quel domaine pose problème.


Échantillon rapide d'une trace de pile, à titre d'exemple - dans ce cas, une erreur s'est produite car la date de CreatedOn date de CreatedOn n'a pas été définie sur l'entité IAComment . Il est toutefois impossible de déterminer à partir de cette trace d'erreur / de pile.

    [SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.]
   System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value) +2127345
   System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value) +232
   System.Data.SqlClient.MetaType.FromDateTime(DateTime dateTime, Byte cb) +46
   System.Data.SqlClient.TdsParser.WriteValue(Object value, MetaType type, Byte scale, Int32 actualLength, Int32 encodingByteSize, Int32 offset, TdsParserStateObject stateObj) +4997789
   System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc) +6248
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
   System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
   System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
   System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10
   System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues) +8084396
   System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) +267

[UpdateException: An error occurred while updating the entries. See the inner exception for details.]
   System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) +389
   System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) +163
   System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) +609
   IADAL.IAController.Save(IAHeader head) in C:\Projects\IA\IADAL\IAController.cs:61
   IA.IAForm.saveForm(Boolean validate) in C:\Projects\IA\IA\IAForm.aspx.cs:198
   IA.IAForm.advance_Click(Object sender, EventArgs e) in C:\Projects\IA\IA\IAForm.aspx.cs:287
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5019

Réponse acceptée

Une option consiste à gérer l' événement ObjectContext.SavingChanges , ce qui vous permet d'effectuer une validation sur des entités avant que les modifications ne soient enregistrées et même d'annuler l'enregistrement si nécessaire. De cette façon, vous pouvez vous assurer que toutes les propriétés non nullables sont définies avant d'essayer de sauvegarder les modifications, et vous évitez de vous fier à la gestion des exceptions.


Réponse populaire

Si tout ce que vous avez à faire est de voir l'exception interne réelle à la place, il vous suffit de placer les modifications de sauvegarde à l'intérieur d'un bloc try, d'attraper l'exception et de l'examiner.

Je le fais tout le temps et cela fonctionne parfaitement.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow