2011-03-17 11 views
172

EF 4.1用のDatabaseInitializer()でモデルを初期化していて、この迷惑なエラーが発生する"Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."このEntityValidationErrorsに移動し、フィールド{System.Data.Entity.Validation.DbEntityValidationResult}が表示されますどのフィールドを初期化することができなかったかについての情報はまったくありません。 このエラーの詳細を表示する方法はありますか?DbValidationExceptionから正確なエラータイプを取得する

物事をクリアするには:

は、私は、文字列の長さの問題を解決する方法を知っています。私が求めているのは、モデルを破っている正確なフィールド名を取得する方法です。

答えて

355

あなたはcatch {...}ブロック内でデバッグモードである間は、 "クイックウォッチ" ウィンドウ(CTRL + ALT + Q)を開くと、そこに貼り付けます。

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors 

このValidationErrorsツリーにドリルダウンすることができます。これらのエラーを即座に把握するのが私が見つけた最も簡単な方法です。最初のエラーだけを気にしてcatchブロックを持っていない可能性がありますビジュアル2012+ユーザーの場合

、あなたも行うことができます。

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage 
+8

これは他の答えよりも優れています:) – Doug

+93

キャッチブロックがない場合、 'ex'を' $ exception'に置き換えて同じ結果を得ることができます。 – Ecyrb

+0

また、 'ex'をw/eで置き換えることを確かめてください。' catch(例外THIS) 'は – Eonasdan

4

まあ、同じ問題がありました。 。私のモデルでは、私は私が財産を持っていたこと考え出した私はそれをinitalizeしようとしたときに「検証は、1つのまたは複数のエンティティのために失敗しました」」EF CTP5で良い働いたが同じエラーで4.1でビルドに失敗しました:

public string Comment {get; set;} 

その後

私は、EF 4.1では、が明示的に設定されていることがあると私は考えています。 :

[StringLength(4000)] 
public string Comment {get; set;} 

助けてくれた。 CTP5には問題はなかったので変です。

+0

私が求めているのは、モデルを破っている正確なプロパティ名を取得する方法です。しかし、私はあなたが[StringLength(Int32.MaxValue)]をプロパティの属性として使用して記述した問題を克服することができました(Ladislav Mrnkaが提案したように、この質問では私はそれについて話をしましたhttp://stackoverflow.com/questions/5346155/ef-code-first-4-1-doesnt-support-nvarcharmax-at-all)Powodzenia! =) –

+0

4.1のモデルに新しいプロパティを追加したときにスローされました。以前は4.1で完全に動作していました。奇妙な。モデル内のすべてのプロパティにアノテーションを追加することで解決しました。 –

122

try/catchブロックでこれを試すことができますか?

catch (DbEntityValidationException dbEx) 
{ 
    foreach (var validationErrors in dbEx.EntityValidationErrors) 
    { 
     foreach (var validationError in validationErrors.ValidationErrors) 
     { 
      Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage); 
     } 
    } 
} 
+1

私が必要としたもの。どうもありがとう! –

+8

コードを変更したくない場合は、私の答えを見てください。 – GONeale

1

が、私はそれが役に立つよりEntityValidationErrorsを作るのSaveChangesラッパーを作成することが判明しました読み:

Public Sub SaveChanges(entities As Entities) 

    Try 
     entities.SaveChanges() 

    Catch ex As DbEntityValidationException 

     Dim msg As New StringBuilder 
     msg.AppendLine(ex.Message) 

     For Each vr As DbEntityValidationResult In ex.EntityValidationErrors 
      For Each ve As DbValidationError In vr.ValidationErrors 
       msg.AppendLine(String.Format("{0}: {1}", ve.PropertyName, ve.ErrorMessage)) 
      Next 
     Next 

     Throw New DbEntityValidationException(msg.ToString, ex.EntityValidationErrors, ex) 

    End Try 

End Sub 

、その後は私のプロジェクト全体

8

最高のソリューに 'のSaveChanges(エンティティ)' から 'entities.SaveChangesを()' に変更私の意見では、この種のエラーを一元的に処理することです。

ちょうどメインDbContextクラスにこのメソッドを追加します。

public override int SaveChanges() 
{ 
    try 
    { 
     return base.SaveChanges(); 
    } 
    catch (DbEntityValidationException ex) 
    { 
     string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage)); 
     throw new DbEntityValidationException(errorMessages); 
    } 
} 

これはあなたのコンテキストのSaveChanges()メソッドを上書きしてしまいますし、あなたはすべてのエンティティの検証エラーを含むカンマ区切りのリストを取得します。

これは役に立ちます。