2013-08-06 23 views
5

Entity Frameworkコードファーストデータベース(V5)に保存する複合クラス(以下のサンプルコードを参照)があります。問題は、データベースに保存されているFooAndOrBarデータでFooClassが使用されていて、FooClassエントリが削除されないようにしたい場合です。 nullになる可能性があるので、外部キーのチェックはFooClassの削除を止めず、自分自身をチェックする必要があります。以下に示すようにEntity FrameworkのValidateEntityが呼び出されません。エントリの削除

class FooClass { ... some properties } 

    class BarClass { ... some properties } 

    class FooAndOrBar 
    { 
     public int Id { get; set; } 
     public FooClass Foo { get; set; } 
     public BarClass Bar { get; set; } 
    } 

したがって、複数のデータベースエントリ横断エントリを検証するための良い方法を以下、私は、Entity FrameworkのValidateEntity方法にテストを追加しました。

protected override DbEntityValidationResult ValidateEntity(
     DbEntityEntry entityEntry, IDictionary<object, object> items) 
    { 
     if (entityEntry.Entity is FooClass && 
      entityEntry.State == EntityState.Delete) 
     {    
      if (... entityEntry.Entity is used in DbContext.FooAndOrBars ...) 
       return new DbEntityValidationResult(... error ...); 
     } 

     return base.ValidateEntity(entityEntry, items); 

    } 

問題は、削除時にValidateEntityが呼び出されないようです。それは理にかなっています(なぜあなたが削除しようとしているものを検証するのですか)。私はUnitOfWork/repositoryパターンを使用し、そこにテストを置くことができますが、それはにおいを感じます。

誰もがこの問題に遭遇し、それをクリーンな方法で解決したことがありますか?あなたの意見は高く評価されます。

パウエルからの回答(下記参照)。

@pawelは、ShouldValidateEntityをオーバーライドして、削除されたアイテムに対してValidateEntityが呼び出されることを指摘しました。他の誰かがこれを便利に見いだすためのコードの例を以下に示します。

/// <summary> 
/// Override ShouldValidateEntity to cause deleted entities to be checked as well 
/// </summary> 
protected override bool ShouldValidateEntity(DbEntityEntry entityEntry) 
{ 
    if (entityEntry.State == EntityState.Deleted) 
     return true; 

    return base.ShouldValidateEntity(entityEntry); 
} 

は、私が実際にエンティティのタイプをチェックすることによってちょうどすべて削除されたアイテムよりも少しタイトなチェックをしたが、それはただのパフォーマンスを改善することです。

+0

最初はコントローラの削除アクションについて考えさせてくれます。 – nocturns2

答えて

11

デフォルトでは、変更および追加されたエンティティのみが検証されます。これは、DbContext.ShouldValidateEntity()メソッドをオーバーライドして、削除されたエンティティに対してもtrueを返すことによって変更できます。

+0

こんにちは@pawel。それはまさに私が必要としていたもので、完璧に機能しました。私は変更を追跡するために私がDbContextで持っているコードでテストしたかもしれませんが、それはスマートな考えではない、バリデーションとトラッキングが混在しています。私は私の答えにサンプルコードを入れました。 –

+0

あなたにはうってつけで、解決策を示すコードを追加していただきありがとうございます。 – Pawel

関連する問題