2016-05-04 2 views
1

ruby​​ on railsに触発エンティティフレームワークに削除コールバックを追加します。私は、トラッキングされたエンティティをループし、エンティティが削除されるたびに呼び出されるインターフェイスを作成するために、SaveChanges()をオーバーライドすることから始めました。エンティティフレームワークで削除コールバックを追加するには?

var changedEntities = ChangeTracker.Entries(); 
foreach (var changedEntity in changedEntities) 
{ 
    if (changedEntity.Entity is IBeforeDelete && changedEntity.State == EntityState.Deleted) 
    { 
     IBeforeDelete saveChange = (IBeforeDelete)changedEntity.Entity; 
     saveChange.BeforeDelete(this, changedEntity); 
    } 
} 

これはかなりうまくいきますが、私は1つの問題を考え出しました。その解決方法はわかりません。エンティティが削除されるとコールバック内に、Changetrackerは、新しく削除されたアイテムを再修正するために更新する必要があります。それをどうすれば解決できますか?それとも別の解決策がありますか?それとも間違っているのですか?あなたがコミットされていないエンティティを除外でき

+0

*または私はそれが間違っているんです*あなたはsaveChange.BeforeDelete' 'に何をすべきかに依存します?。 –

答えて

1

いい質問で、残りの...

var changedEntities = Context.ChangeTracker 
    .Entries<TEntity>() 
    .Where(e => e.State != EntityState.Detached) 
    .Select(e => e.Entity); 

とロックを変更します。私があなたを正しく理解していれば、BeforeDeleteの実装では、BeforeDeleteが呼び出される必要がある別のエントリも削除される可能性があります。これは再帰的に永遠に進む可能性があるので、最後のバッチが処理された後に新しいものが追加されたかどうかを確認するために、変更トラッカーのエントリを再帰的にチェックすることしか考えられません。

未テスト:

public override int SaveChanges() 
{ 
    var processed = new List<DbEntityEntry>(); 
    var entries = ChangeTracker.Entries(); 

    do 
    { 
     foreach (var entry in entries) 
     { 
      processed.Add(entry); 

      if (entry.Entity is IBeforeDelete && entry.State == EntityState.Deleted) 
      { 
       IBeforeDelete saveChange = (IBeforeDelete)entry.Entity; 
       saveChange.BeforeDelete(this, entry); 
      } 
     } 
    } while ((entries = ChangeTracker.Entries().Except(processed)).Any()); 

    return base.SaveChanges(); 
} 
0

は、あなたの "if" ブロック

lock(changedEntity.Entity){ ... interface code } 
関連する問題