EF Code First:如何从nuget包控制台中看到“EntityValidationErrors”属性?
我对此感到不知所措:
我已经定义了我的类为一个entity framework(4.1.3)代码的第一种方法。 一切都很好(我正在创build表等),直到我开始种子。
现在当我做了
Add-Migration "remigrate" ; Update-Database;
我在包控制台上得到一个错误“一个或多个实体的validation失败。有关更多详细信息,请参阅”EntityValidationErrors“属性。
我在我的Seed()方法中有一个断点,但是因为我在控制台上运行这个项目时没有运行,我很无知,如何去详细信息(PS – 我已经看到线程validation失败对于一个或多个实体,同时使用entity framework保存对SQL Server数据库的更改 ,显示如何查看该属性。)
我知道我的Seed()方法有一个问题,因为如果我在方法调用后立即返回,错误就会消失。 那么如何设置我的断点,以便我可以看到validation错误是什么? 有点失落了 还是有一些其他的方式来追踪它在nuget控制台?
我最近也被这个烦恼了。 我通过在Seed方法中的Configuration类中放置一个包装器函数来解决这个问题,并将调用replace为调用我的函数的SaveChanges
。 这个函数只需枚举EntityValidationErrors
集合中的错误,并在Exception消息列出单个问题的地方重新引发exception。 这使得输出显示在NuGet包pipe理器控制台中。
代码如下:
/// <summary> /// Wrapper for SaveChanges adding the Validation Messages to the generated exception /// </summary> /// <param name="context">The context.</param> private void SaveChanges(DbContext context) { try { context.SaveChanges(); } catch (DbEntityValidationException ex) { StringBuilder sb = new StringBuilder(); 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.ToString(), ex ); // Add the original exception as the innerException } }
只需在您的种子方法中将调用replace为context.SaveChanges()
和SaveChanges(context)
。
用部分类定义扩展您的DBContext类!
如果你看看你的DbContext的类定义,它将如下所示:
// DatabaseContext.cs -- This file is auto generated and thus shouldn't be changed. public partial class [DatabaseContextName] : DbContext { ... }
所以,在另一个文件中,你可以创build相同的定义,并覆盖你想要的部分。
// partialDatabaseContext.cs -- you can safely make changes // that will not be overwritten in here. public partial class [DatabaseContextName] : DbContext { // Override defaults here }
使用部分类的整个想法 – 你注意到DbContext是一个部分类 –就是你可以扩展一个已经生成的类(或者把类组织成多个文件),在我们的例子中,我们也想覆盖 SaveChanges方法从一个添加到DbContext的分类中 。
通过这种方式,我们可以从现有的所有DbContext / SaveChanges调用中获取错误debugging信息,而不必更改您的种子代码或开发代码。
这是我会做的( 注意不同的是,我只是在我们自己创作的DbContext部分类中重写SaveChanges方法,而不是生成的 )。 另外,确保你的部分课程使用了正确的名称空间,否则你将头撞墙。
public partial class Database : DbContext { public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException ex) { var sb = new StringBuilder(); 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.ToString(), ex ); // Add the original exception as the innerException } } }
我将Richards的答案转换为扩展方法:
public static int SaveChangesWithErrors(this DbContext context) { try { return context.SaveChanges(); } catch (DbEntityValidationException ex) { StringBuilder sb = new StringBuilder(); 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.ToString(), ex ); // Add the original exception as the innerException } }
这样的电话:
context.SaveChangesWithErrors();
我将Craigvl的版本转换为C#,我不得不添加context.SaveChanges(); 以便它为我工作如下。
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.StringBuilder(); 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.ToString()); }
理查德感谢让我在正确的道路(同样的问题)下面是一个替代没有包装这在我的迁移configuration种子方法:
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 StringBuilder 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.ToString()) End Try End Sub
然后能够在包pipe理器控制台中看到exception。 希望这有助于某人。
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<ApplicationUser> > > { > public AppDb(): base("DefaultConnection", throwIfV1Schema: false) > { > > } > > public static AppDb Create() >{ >return new AppDb(); >} **New:** >public class AppDb1 : IdentityDbContext<ApplicationUser> >{ >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<DAL.AppDb1> { 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
- 重命名ASP.NET MVC项目导致多种types的控制器错误
- 如何在ASP.NET MVC 3中创build自定义编辑器/显示模板?
- 如何将额外的命名空间添加到Razor页面而不是@using声明?
- 从ASP.NET MVC 3开始,MicrosoftAjax.js,MicrosoftMvcAjax.js和MicrosoftMvcValidation.js是否被废弃?
- 一个列表的ViewModelvalidation
- 为什么Razor _layout.cshtml在文件名中有一个前导下划线?
- ASP.NET MVC DropDownListFortypes为List <string>的模型
- MVC3 Url.Action查询string生成
- 如何在一个解决scheme中的多个项目之间共享脚本?