[英]Entity Framework Core DbUpdateException detailed information
I am just getting started with EF Core in my full .net 4.5.2 project and am trying to do an integration test to validate I can insert a new student.我刚刚在我的完整 .net 4.5.2 项目中开始使用 EF Core,并且正在尝试进行集成测试以验证我可以插入一个新学生。
The issue is, I want to be able to get better information from the exception being thrown as to why it is not inserting into the database.问题是,我希望能够从抛出的异常中获得更好的信息,说明为什么它没有插入到数据库中。
Here is my integration test code:这是我的集成测试代码:
[Fact]
public void save_the_new_student_to_the_database()
{
var fixture = new Fixture();
var optionsBuilder = new DbContextOptionsBuilder<TestDbContext>();
//optionsBuilder.UseInMemoryDatabase();
optionsBuilder.UseSqlServer("Server = (localdb)\\mssqllocaldb; Database = afmil_Test_next; Trusted_Connection = True; "
);
using (var context = new TestDbContext(optionsBuilder.Options))
{
var command = fixture.Create<PostRegisterStudentCommand>();
var handler = new PostRegisterStudentCommandHandler(context);
try
{
handler.Handle(command);
}
catch (DbUpdateException e)
{
var sb = new StringBuilder();
sb.AppendLine($"DbUpdateException error details - {e?.InnerException?.InnerException?.Message}");
foreach (var eve in e.Entries)
{
sb.AppendLine($"Entity of type {eve.Entity.GetType().Name} in state {eve.State} could not be updated");
}
sb.ShouldBeNull();
}
var dbStudent = context.Students.FirstOrDefault();
dbStudent.ShouldNotBeNull();
dbStudent.User.FirstName.ShouldBe(command.FirstName);
}
}
I got the exception catch part from an EF 6 stackoverflow answer .我从 EF 6 stackoverflow answer 中得到了异常捕获部分。
I've search everything I can think of to find a example of extracting entity validation issues (DbEntityValidationException from EF6) in EF Core but cannot find anything that seems to work.我已经搜索了我能想到的所有内容,以在 EF Core 中找到提取实体验证问题(来自 EF6 的 DbEntityValidationException)的示例,但找不到任何似乎有效的内容。
As a suggestion from this EF Core github issue , I attempted to do some annotation validation like this .作为来自这个 EF Core github 问题的建议,我尝试像这样进行一些注释验证。 But this didn't find the issues that the db was having with my student object.
但这并没有发现数据库与我的学生对象存在的问题。
Indeed EF7 lacks the validation that it is available in EF6.事实上,EF7 缺乏它在 EF6 中可用的验证。 This seems to be a design choice as validation is assumed before models are sent to be saved (and also DB constraints might be used as a safety net).
这似乎是一种设计选择,因为在发送模型以进行保存之前假设了验证(并且 DB 约束也可能用作安全网)。
This article shows how to manually perform validations before saving data. 本文展示了如何在保存数据之前手动执行验证。 However, beware that this works for data annotation only.
但是,请注意这仅适用于数据注释。 My slightly changed version is the following:
我稍微改变的版本如下:
public void Validate()
{
var entities = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified)
.Select(e => e.Entity);
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(entity, validationContext, validateAllProperties: true);
}
}
My advice is to have a method to handle both type of exceptions (validation and database), something like the following:我的建议是使用一种方法来处理两种类型的异常(验证和数据库),如下所示:
try
{
Validate();
Context.SaveChanges();
}
catch(ValidationException exc)
{
Logger.LogError(exc, $"{nameof(SaveChanges)} validation exception: {exc?.Message}");
return false;
}
catch (DbUpdateException exc)
{
Logger.LogError(exc, $"{nameof(SaveChanges)} db update error: {exc?.InnerException?.Message}");
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.