2012-10-02 8 views
8

DbContext.SaveChanges()メソッドをオーバーライドし、ISoftDeleteインターフェイスを実装するエンティティの削除を元に戻して、プロジェクトでソフト削除機能を実装しようとしています。 。私は「削除」状態にあり、ISoftDeleteを実装するすべてのエントリのための私のSoftDelete()メソッドを呼び出していますSaveChanges()方法でアソシエーションによるエンティティの削除のオーバーライド

interface ISoftDelete 
{ 
    bool IsDeleted { get; set; } 
} 

var entries = this.ChangeTracker.Entries().Where(x => (x.State == EntityState.Deleted) && x.Entity is ISoftDelete) 
        .ToList(); 
       entries.ForEach(SoftDelete); 

次のように私のSoftDelete()方法は次のとおりです。

これは、他のものと1対1の関連性を持つエンティティを実行するまで完全に機能します。その時点で、例外はこのエラーでスローされます。

{"A relationship from the 'ChildParent' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'Parent' must also in the 'Deleted' state."}

はそのエンティティのすべての関連付けを取得し、同様にそれらのために削除された状態を変更する方法はありますか?

私は既に実際の関連エンティティへの参照を取得しようとしましたが、エンティティのEntityStateDeletedの代わりにUnchangedに設定されています。

+3

アソシエーション自体が削除されているとマークされていると思いますが(アソシエーションはEFでは別のオブジェクトとして扱われますが)、関連するエンティティは処理されません。現在、EFが関連付けを削除しようとすると、関連エンティティに削除済みのマークが付いていないため、関連付けられていないことがあります。私は、外部キーがnullableではないと仮定しているため、エンティティを削除するには関連するエンティティを削除する必要があります(カスケード削除)。あなたはこのスレッドをチェックすることができます:http://stackoverflow.com/questions/10300156/ivalidatableobject-is-useless-for-ef-navigation-properties/10304323#10304323。それは、関連するオブジェクトに到達する方法を示すので役立ちます。 – Pawel

+0

関連するオブジェクトを取得するのに役立ちました、ありがとうございます。しかし、関係の1つの状態を変更しようとすると、「関係の終わりの1つがKeyEntryの場合、関係の状態を変更できません」という奇妙なエラーが発生します。 – Jonathan

+0

[この回避策](http://connect.microsoft.com/VisualStudio/feedback/details/513174/unable-to-refresh-some-items-in-the-objectcontext)を見ましたか? –

答えて

0

一般に、親子関係の子を最初にソフト削除する必要があります。一番上の親から始めて、子どもたちのやり方を繰り返す。アクセスしたすべてのアイテムにマークを付けることで、すでにソフト削除されているかどうかを追跡できます(バックリファレンスの場合)。

「ビジネスオブジェクト」という概念がある場合は、ナビゲーションを容易にするためにChildsParentプロパティを追加できます。さもなければ、あなたは子の関係が自明でなくても、各親に対してこれを "手作業でコード化"する必要があります。

また、1つのLINQステートメントを使用すると、実際のトラバースを制御できません。

私は上記が多くの仕事のように思えますが、必要な関係情報を自動的に推論するEFの仕組みをどのようにデバイス化するかを検討してください。あなたはこのようなことを適切に終わらせるでしょう。