Quantcast
Channel: Darkthread
Viewing all articles
Browse latest Browse all 428

EntityFramework烏龍記-SaveChanges出現OriginalValues取值錯誤

$
0
0

使用Entity Framework新増資料,SaveChanges()時出現以下錯誤:

System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
   於 System.Data.Entity.Internal.InternalContext.SaveChanges()
   於 System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   於 System.Data.Entity.DbContext.SaveChanges()

*** DbEntityValidationException.EntityValidationErrors ***
Failed to dump exception: Error getting value from 'OriginalValues' on 'System.Data.Entity.Infrastructure.DbEntityEntry'.

深入檢查發現,要寫入的資料表有個不允許NULL的VARCHAR欄位,為新増資料物件對應該欄位的字串屬性忘了給值(呈現null)引發,修正後錯誤消失。原因很單純問題不難解,只是錯誤訊息玄疑了點。有此經驗,下回看到DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. 別看 EntityValidationErrors 以免愈看愈花,仔細檢查有沒有欄位少給值、長度不符… 就對了。

感謝讀者ace提醒,本案是一起烏龍。上述錯誤訊息是由自製函數產生,其中"Failed to dump exception"已提示為印出輸出例外資訊時出錯,Error getting value from 'OriginalValues' 並非EntityValidationErrors內容,一時失察錯判問題來源,先向大家致歉,晚點再提供更多細節。

[2016-06-04更新]

檢查程式後,查出問題出在當初便宜行事,想用SerializeObject將EntityValidationErrors序列化填入Log,加上覺得短短幾行不致出錯,心存僥倖沒實測驗證,藏下一個EntityValidationErrors無法用Json.NET SerializeObject()的Bug,再遇上射茶包精神不集中鬧了笑話,請大家見諒。匯出錯誤訊息的程式片段如下:

    sb.AppendLine("*** DbEntityValidationException.EntityValidationErrors ***");
try {
        sb.AppendLine(JsonConvert.SerializeObject(ex.EntityValidationErrors));
    }
catch (Exception jsonEx)
    {
        sb.AppendLine("Failed to dump exception: " + jsonEx.Message);
    }

正確寫法應如ace的做法:

    sb.AppendLine("*** DbEntityValidationException.EntityValidationErrors ***");
try {
        sb.AppendLine(JsonConvert.SerializeObject(ex.EntityValidationErrors
                    .SelectMany(o => o.ValidationErrors)
                    .Select(o => o.ErrorMessage).ToArray()));
    }
catch (Exception jsonEx)
    {
        sb.AppendLine("Failed to dump exception: " + jsonEx.Message);
    }

寫法對了,錯誤訊息根本清楚到驚天地泣鬼神,當初搞得一頭霧水全怪自己豬頭:

DbEntityValidationException.EntityValidationErrors ***
["Blah 欄位是必要項。"]

記取教訓:

寫完不測必有報應 寫完不測必有報應 寫完不測必有報應
眼拙心粗夏夕夏景 眼拙心粗夏夕夏景 眼拙心粗夏夕夏景

請大家以我為誡。Orz


Viewing all articles
Browse latest Browse all 428

Trending Articles