[C#.NET][Entity Framework] EF6 重新引發 DbEntityValidationException 例外

[C#.NET][Entity Framework] EF6 重新引發 DbEntityValidationException 例外

當我們調用 SaveChanges() 方法時,常常一不小心就引發 DbEntityValidationException,它是 EF 要產生 SQL 語句前的檢查,屬於應用程式等級的檢查,它可讓系統在開發階段很快地掛掉,程式設計師能快速地找到問題點,縮短除錯的時間,但 Message 所描述的內容,『一個或多個實體的驗證失敗。如需詳細資料,請參閱 'EntityValidationErrors' 屬性。』,這線索實在太少,令人摸不著頭緒,紀錄 Message,對除錯來講一點用處都沒有。

image

 

所以,我們必須要處理 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

Image result for microsoft+mvp+logo