2013年3月4日月曜日

[EntityFramework]SaveChanges() 時の検証

EntityFramework5で確認


DBの最大文字列長に合わせて、エンティティにもMaxLengthプロパティが表示されるけど


MaxLengthより長い文字列をエンティティに突っ込んでSaveChanges()したら何が起こるの?と思ってやってみた。
(普通はデータアノテーションとかで事前に検証するから、なかなかそんな状況にならないと思うけど)

エンティティのプロパティに文字列をセットした時点では何も起こらず。
SaveChanges()時に例外発生。DbEntityValidationExceptionとな。


SQLExceptionになると思ってたけど、EntityFramework側でちゃんと検証してるんだ…。
検証の内容を出力するには下記のようなコードになった。深い。深いぞう。

                try
                {
                    db.SaveChanges();
                }
                catch (System.Data.Entity.Validation.DbEntityValidationException ex)
                {
                    foreach (var errors in ex.EntityValidationErrors)
                    {
                        foreach (var error in errors.ValidationErrors)
                        {
                            System.Diagnostics.Trace.WriteLine(error.ErrorMessage);    // VisualStudioの出力に表示
                        }
                    }
                    throw ex;
                }



■出力に表示されたエラーメッセージ
フィールド Name は、最大の長さが '50' の文字列型または配列型でなければなりません。



SaveChanges()時の検証の実行は DbContextConfiguration.ValidateOnSaveEnabled プロパティで制御できるみたい。デフォルトはtrue。(EntityFramework5)
http://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbcontextconfiguration.validateonsaveenabled%28v=vs.103%29.aspx


試しにfalseにして、先ほどのコードを動かしてみると
                db.Configuration.ValidateOnSaveEnabled = false;

先ほどと違う例外発生。 DbUpdateExceptionとな。


InnerExceptionのInnerException(深い)にSQLExceptionいた!
ちゃんとEFの検証が無効になって、SQLが発行されているんですなあ~(当たり前)


古いバージョンのEntityFramework2.0だとValidateOnSaveEnabled自体が無かった。
デフォルトでEF側の検証もされないようであった(そもそも検証の仕組みが無い?)