如何在Entity Framework Core 3.1.31中获取实体验证错误
EF Core 3.1 捕获实体验证错误的替代方案
EF Core 中已移除 EF6 里的 DbEntityValidationException,验证错误通过两种方式暴露:要么手动触发验证获取错误,要么在调用 SaveChanges 时抛出 DbUpdateException,其内部嵌套的 ValidationException 包含详细错误信息。以下是两种适配原代码逻辑的实现方式:
方式一:手动提前验证(推荐,与原代码结构最接近)
在调用 SaveChanges 前主动触发实体验证,直接获取与 EF6 结构类似的错误集合,无需捕获异常:
// 先执行实体验证 var validationErrors = context.GetValidationErrors(); if (validationErrors.Any()) { var sb = new StringBuilder(); foreach (var eve in validationErrors) { sb.AppendLine($"Entity of type {eve.Entry.Entity.GetType().Name} in state {eve.Entry.State} has the following validation errors:<br />"); foreach (var ve in eve.ValidationErrors) { sb.AppendLine($" - Property: {ve.PropertyName}, Error: {ve.ErrorMessage}<br />"); } } retval.ErrorMessages.Add(sb.ToString()); // 可选:终止保存操作,或继续调用SaveChanges让EF抛出异常 return; } // 验证通过再执行保存 context.SaveChanges();
方式二:捕获SaveChanges时的异常
如果需要在保存阶段捕获验证错误,可以捕获 DbUpdateException 并解析其内部的 ValidationException:
try { context.SaveChanges(); } catch (DbUpdateException dbexc) { if (dbexc.InnerException is ValidationException validationExc) { var sb = new StringBuilder(); // 遍历上下文变更追踪器中的所有实体,获取对应验证错误 foreach (var entry in context.ChangeTracker.Entries()) { var entryValidationResult = entry.GetValidationResult(); if (!entryValidationResult.IsValid) { sb.AppendLine($"Entity of type {entry.Entity.GetType().Name} in state {entry.State} has the following validation errors:<br />"); foreach (var ve in entryValidationResult.ValidationErrors) { sb.AppendLine($" - Property: {ve.PropertyName}, Error: {ve.ErrorMessage}<br />"); } } } retval.ErrorMessages.Add(sb.ToString()); } // 处理其他DbUpdateException场景 }
关键说明
GetValidationErrors()方法返回的IEnumerable<EntityValidationResult>与 EF6 中DbEntityValidationException.EntityValidationErrors结构完全匹配,能直接复用原代码的遍历逻辑。- EF Core 默认会在
SaveChanges时自动执行验证,若验证失败则抛出DbUpdateException,其InnerException为ValidationException,包含所有验证结果。
内容的提问来源于stack exchange,提问作者geoff swartz
相关产品推荐
相关产品推荐

