Je suis à court de cela:
J’ai défini mes classes pour une première approche de code d’entité (4.1.3). Tout allait bien (je créais les tables, etc.) jusqu’à ce que je commence à semer.
Maintenant, quand je fais la
Add-Migration "remigrate" ; Update-Database;
J’ai une erreur sur la console du package “La validation a échoué pour une ou plusieurs entités. Voir la propriété ‘EntityValidationErrors’ pour plus de détails.”
J’ai un point d’arrêt dans ma méthode Seed () mais comme je lance cela sur la console lorsque le projet n’est pas lancé, je ne sais pas comment accéder aux détails (PS – J’ai vu le thread de validation échoué) pour une ou plusieurs entités lors de l’enregistrement des modifications apscopes à la firebase database SQL Server à l’aide d’Entity Framework qui montre comment je peux voir la propriété.)
Je sais que ma méthode Seed () a un problème car si je mets un retour juste après l’appel de la méthode, l’erreur disparaît. Alors, comment définir mon point d’arrêt pour que je puisse voir quelle est l’erreur de validation? Kinda perdu Ou existe-t-il une autre façon de le retrouver dans la console nuget?
Cela m’a énervé récemment aussi. Je l’ai corrigé en plaçant une fonction wrapper dans la classe Configuration dans la méthode Seed et SaveChanges
remplacé les appels à SaveChanges
par des appels à ma fonction. Cette fonction énumérera simplement les erreurs dans la collection EntityValidationErrors
et relance une exception où le message Exception répertorie les problèmes individuels. Cela fait apparaître la sortie dans la console du gestionnaire de paquets NuGet.
Code suit:
/// /// Wrapper for SaveChanges adding the Validation Messages to the generated exception /// /// The context. private void SaveChanges(DbContext context) { try { context.SaveChanges(); } catch (DbEntityValidationException ex) { SsortingngBuilder sb = new SsortingngBuilder(); foreach (var failure in ex.EntityValidationErrors) { sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType()); foreach (var error in failure.ValidationErrors) { sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage); sb.AppendLine(); } } throw new DbEntityValidationException( "Entity Validation Failed - errors follow:\n" + sb.ToSsortingng(), ex ); // Add the original exception as the innerException } }
Remplacez simplement les appels à context.SaveChanges()
par SaveChanges(context)
dans votre méthode de graine.
Étendez votre classe DBContext déjà avec une définition de classe partielle!
Si vous regardez la définition de classe de votre DbContext, ce sera comme suit:
// DatabaseContext.cs -- This file is auto generated and thus shouldn't be changed. public partial class [DatabaseContextName] : DbContext { ... }
Ainsi, dans un autre fichier, vous pouvez créer la même définition et remplacer les parties souhaitées.
// partialDatabaseContext.cs -- you can safely make changes // that will not be overwritten in here. public partial class [DatabaseContextName] : DbContext { // Override defaults here }
L’idée générale des classes partielles – vous avez remarqué que DbContext est une classe partielle – est que vous pouvez étendre une classe qui a été générée (ou organiser des classes en plusieurs fichiers) et dans notre cas, nous voulons également remplacer la méthode SaveChanges à partir d’une classe partielle qui ajoute à DbContext .
De cette façon, nous pouvons obtenir des informations de débogage d’erreur à partir de tous les appels DbContext / SaveChanges existants et ne pas avoir à modifier votre code de démarrage ou votre code de développement.
C’est ce que je ferais ( NOTE la différence est que je remplace simplement la méthode SaveChanges dans notre propre classe partielle DbContext créée, PAS THE GENERATED ONE ). De plus, assurez-vous que la classe partielle utilise le bon espace de noms ou vous cognez la tête contre le mur.
public partial class Database : DbContext { public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException ex) { var sb = new SsortingngBuilder(); foreach (var failure in ex.EntityValidationErrors) { sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType()); foreach (var error in failure.ValidationErrors) { sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage); sb.AppendLine(); } } throw new DbEntityValidationException( "Entity Validation Failed - errors follow:\n" + sb.ToSsortingng(), ex ); // Add the original exception as the innerException } } }
J’ai converti la réponse de Richards à une méthode d’extension:
public static int SaveChangesWithErrors(this DbContext context) { try { return context.SaveChanges(); } catch (DbEntityValidationException ex) { SsortingngBuilder sb = new SsortingngBuilder(); foreach (var failure in ex.EntityValidationErrors) { sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType()); foreach (var error in failure.ValidationErrors) { sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage); sb.AppendLine(); } } throw new DbEntityValidationException( "Entity Validation Failed - errors follow:\n" + sb.ToSsortingng(), ex ); // Add the original exception as the innerException } }
Appelez comme ceci:
context.SaveChangesWithErrors();
J’ai converti la version de craigvl en C # Je devais append context.SaveChanges (); pour que cela fonctionne pour moi comme ci-dessous.
try { byte[] bytes = System.IO.File.ReadAllBytes(@"C:\Users\sheph_000\Desktop\Rawr.png"); Console.WriteLine(bytes); context.BeverageTypes.AddOrUpdate( x => x.Name, new AATPos.DAL.Entities.BeverageType { ID = 1, Name = "Sodas" } ); context.Beverages.AddOrUpdate( x => x.Name, new AATPos.DAL.Entities.Beverage { ID = 1, Name = "Coke", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" }, new AATPos.DAL.Entities.Beverage { ID = 2, Name = "Fanta", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" }, new AATPos.DAL.Entities.Beverage { ID = 3, Name = "Sprite", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" }, new AATPos.DAL.Entities.Beverage { ID = 4, Name = "Cream Soda", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" }, new AATPos.DAL.Entities.Beverage { ID = 5, Name = "Pepsi", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" } ); context.SaveChanges(); } catch (System.Data.Entity.Validation.DbEntityValidationException ex) { var sb = new System.Text.SsortingngBuilder(); foreach (var failure in ex.EntityValidationErrors) { sb.AppendFormat("{0} failed validation", failure.Entry.Entity.GetType()); foreach (var error in failure.ValidationErrors) { sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage); sb.AppendLine(); } } throw new Exception(sb.ToSsortingng()); }
Richard merci de me mettre sur le bon chemin (avait le même problème) ci-dessous est une alternative sans le wrapper cela a fonctionné pour moi dans la méthode de graine de configuration de la migration:
Protected Overrides Sub Seed(context As NotificationContext) Try context.System.AddOrUpdate( Function(c) c.SystemName, New E_NotificationSystem() With {.SystemName = "System1"}, New E_NotificationSystem() With {.SystemName = "System2"}, New E_NotificationSystem() With {.SystemName = "System3"}) context.SaveChanges() Catch ex As DbEntityValidationException Dim sb As New SsortingngBuilder For Each failure In ex.EntityValidationErrors sb.AppendFormat("{0} failed validation" & vbLf, failure.Entry.Entity.[GetType]()) For Each [error] In failure.ValidationErrors sb.AppendFormat("- {0} : {1}", [error].PropertyName, [error].ErrorMessage) sb.AppendLine() Next Next Throw New Exception(sb.ToSsortingng()) End Try End Sub
A ensuite pu voir l’exception dans la console du gestionnaire de paquets. J’espère que cela aide quelqu’un.
I Also had same model validation problem but successfully catch by myself after lot of thinking; I use reverse engineering method to catch the problem out of Over 80 + Model Classes; 1> Made copy of dbcontext, changing the name (I add "1" at end and make respective changes in class constructor and initialization etc. Old: >public class AppDb : IdentityDbContext > > { > public AppDb(): base("DefaultConnection", throwIfV1Schema: false) > { > > } > > public static AppDb Create() >{ >return new AppDb(); >} **New:** >public class AppDb1 : IdentityDbContext >{ >public AppDb1() >: base("DefaultConnection", throwIfV1Schema: false) >{ >} > >public static AppDb1 Create() > { > return new AppDb1(); > }` ... 2> Make changes to Codefirst Migration Configuration from Old DbContext to my new Context. > internal sealed class Configuration : > DbMigrationsConfiguration { public Configuration() { > AutomaticMigrationsEnabled = false; } protected override void > Seed(DAL.AppDb1 context) {` 3> Comment the Dbsets in new DbContext which was doubt. 4> Apply update migration if succeeded the probelm lye in Commented section. 5> if not then commented section is clear of bug clear. 6> repeat the (4) until found the right place of bug. 7> Happy Codding