[C#.NET][Entity Framework] EF6 重新引發 DbEntityValidationException 例外
當我們調用 SaveChanges() 方法時,常常一不小心就引發 DbEntityValidationException,它是 EF 要產生 SQL 語句前的檢查,屬於應用程式等級的檢查,它可讓系統在開發階段很快地掛掉,程式設計師能快速地找到問題點,縮短除錯的時間,但 Message 所描述的內容,『一個或多個實體的驗證失敗。如需詳細資料,請參閱 'EntityValidationErrors' 屬性。』,這線索實在太少,令人摸不著頭緒,紀錄 Message,對除錯來講一點用處都沒有。
所以,我們必須要處理 EntityValidationErrors 屬性,它是 DbEntityValidationResult 集合,
調用 SaveChange 捕捉 DbEntityValidationException 例外,EntityValidationErrors 它是 DbEntityValidationResult 集合,裡面裝載著 EF 的檢查錯誤,我想要重新包裝一下 Message,至少讓我自己看得懂 ,然後再重新引發 DbEntityValidationException 例外
try
{
ThsmmDbContext db = new ThsmmDbContext();
db.Materials.Add(new Material());
db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("{0}Validation Errors:{1}", Environment.NewLine, Environment.NewLine);
string indentation = "\t - ";
foreach (var entity in ex.EntityValidationErrors)
{
builder.AppendFormat("[{0}]", entity.Entry.Entity.GetType().Name);
foreach (var error in entity.ValidationErrors)
{
builder.AppendFormat("{0}{1}[{2} - {3}]", Environment.NewLine, indentation, error.PropertyName, error.ErrorMessage);
}
}
var msg = builder.ToString();
var exception = new DbEntityValidationException(msg, ex.EntityValidationErrors);
var log = LogManager.GetCurrentClassLogger();
log.Error(exception, "更新資料庫失敗");
throw exception;
}
最後將它們變成擴充方法
public static class DbEntityExceptionExtension
{
public static DbEntityValidationException ThrowDbEntityValidationException(this DbEntityValidationException e)
{
var errorMessage = e.GetValidationErrorMessage();
var result = new DbEntityValidationException(errorMessage, e.EntityValidationErrors);
return result;
}
public static string GetValidationErrorMessage(this DbEntityValidationException e)
{
string result;
var errorMessage = e.EntityValidationErrors
.Select(p => p.GetValidationResult())
.Aggregate(string.Empty, (current, next) => $"{current}{Environment.NewLine}{next}");
result = $"{e}{Environment.NewLine}Validation Errors:{errorMessage}";
return result;
}
public static string GetValidationResult(this DbEntityValidationResult validationResult)
{
string result;
var entityName = $"[{validationResult.Entry.Entity.GetType().Name}]";
string indentation = "\t - ";
var errorMessage = validationResult.ValidationErrors.Select(p => $"[{p.PropertyName} - {p.ErrorMessage}]")
.Aggregate(string.Empty, (current, next) => current + (Environment.NewLine + indentation + next));
result = $"{entityName}{errorMessage}";
return result;
}
}
調用端,調用 ThrowDbEntityValidationException 方法
catch (DbEntityValidationException ex)
{
var s_log = LogManager.GetCurrentClassLogger();
var exception = ex.ThrowDbEntityValidationException();
s_log.Error(exception, "更新資料庫失敗");
throw exception;
}
文章出自:http://www.dotblogs.com.tw/yc421206/archive/2015/11/02/153774.aspx
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET