[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