J'ai la situation où j'initialise mon modèle dans DatabaseInitializer () pour EF 4.1 et j'obtiens cette erreur ennuyeuse "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."
Donc, je vais à cette EntityValidationErrors et il y a un champ {System.Data.Entity.Validation.DbEntityValidationResult}
qui ne me donne aucune information sur le champ qu'il n'a pas pu initialiser . Existe-t-il un moyen d'obtenir plus d'informations sur cette erreur?
Pour clarifier les choses:
Je sais comment résoudre le problème de longueur de chaîne. Ce que je demande, c'est comment obtenir le nom de champ exact qui brise le modèle.
ex
par$exception
et obtenir le même résultat.ex
par w / e votrecatch (Exception THIS)
estSystem.Linq.Enumerable.ToList(System.Linq.Enumerable.ToList(((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors)[0].ValidationErrors)[0].ErrorMessage
Vous pourriez essayer ceci dans un bloc try / catch?
catch (DbEntityValidationException dbEx) { foreach (var validationErrors in dbEx.EntityValidationErrors) { foreach (var validationError in validationErrors.ValidationErrors) { Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage); } } }
la source
La meilleure solution à mon avis est de gérer ce type d'erreurs de manière centralisée.
ajoutez simplement cette méthode à la
DbContext
classe principale :public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException ex) { string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage)); throw new DbEntityValidationException(errorMessages); } }
Cela écrasera la
SaveChanges()
méthode de votre contexte et vous obtiendrez une liste séparée par des virgules contenant toutes les erreurs de validation d'entité.espérons que cela est utile.
la source
Eh bien, j'ai eu le même problème. Mon modèle fonctionnait bien dans EF CTP5, mais n'a pas réussi à intégrer la version 4.1 avec la même erreur "" La validation a échoué pour une ou plusieurs entités "lorsque j'ai essayé de l'initaliser. J'ai découvert que j'avais la propriété:
public string Comment {get; set;}
Ensuite, dans la méthode seed dans l'initialiseur surchargé, j'ai eu un commentaire assez long (environ 600 lettres).
Je pense que le point est le suivant: dans EF 4.1, vous devez définir explicitement des annotations de données dans certains cas. Pour moi, définir:
[StringLength(4000)] public string Comment {get; set;}
aidé. C'est bizarre car CTP5 n'a eu aucun problème avec ça.
la source
J'ai trouvé utile de créer un wrapper SaveChanges qui rend les EntityValidationErrors plus lisibles:
Public Sub SaveChanges(entities As Entities) Try entities.SaveChanges() Catch ex As DbEntityValidationException Dim msg As New StringBuilder msg.AppendLine(ex.Message) For Each vr As DbEntityValidationResult In ex.EntityValidationErrors For Each ve As DbValidationError In vr.ValidationErrors msg.AppendLine(String.Format("{0}: {1}", ve.PropertyName, ve.ErrorMessage)) Next Next Throw New DbEntityValidationException(msg.ToString, ex.EntityValidationErrors, ex) End Try End Sub
puis a changé 'entity.SaveChanges ()' en 'SaveChanges (entity)' dans tout mon projet
la source
Je sais que c'est une vieille question mais voici ma réponse:
catch (DbEntityValidationException ex) { String.Join("\n", ex.EntityValidationErrors .SelectMany(x => x.ValidationErrors) .Select(x => x.ErrorMessage) .ToArray()); }
et si vous utilisez d'abord le code, vous pouvez également globaliser vos messages d'erreur à l'aide de plusieurs fichiers de ressources
Par exemple, j'ai ces deux fichiers de ressources séparés, un pour l'erreur et un pour le nom de la propriété et je les utilise comme suit:
public class Person { [Required(ErrorMessageResourceName = "required",ErrorMessageResourceType =typeof(ErrorMessages))] [MaxLength(100,ErrorMessageResourceName = "maxLength", ErrorMessageResourceType = typeof(ErrorMessages))] [Display(Name = "FirstName",ResourceType = typeof(Properties))] public string FirstName { get; set; } }
Comme vous pouvez le voir, j'ai complètement traduit mes messages d'erreur, y compris les noms de propriétés, afin que je puisse ensuite les utiliser dans l'utilisateur plus tard, par exemple:
la source