8

DbContext.SaveChanges()メソッドをオーバーライドし、インターフェイスを実装するエンティティの削除を元に戻すことで、プロジェクトにソフト削除機能を実装しようとしていISoftDeleteます。

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

このSaveChanges()メソッドでは、「削除済み」状態にあり、。を実装するすべてのエントリに対してSoftDelete()メソッドを呼び出していますISoftDelete

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

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

private void SoftDelete(DbEntityEntry entry)
{
    if (entry.State == EntityState.Deleted && entry.Entity is ISoftDelete)
    {
        entry.Reload();
        var entity = (ISoftDelete)entry.Entity;
        entity.IsDeleted = true;
        entry.State = EntityState.Modified;
    }
}

これは、他の何かと1対1の関連付けを持つエンティティに遭遇するまで完全に機能します。その時点で、次のエラーで例外がスローされます。

{"'ChildParent'AssociationSetからの関係は'Deleted'状態です。多重度の制約がある場合、対応する'Parent'も'Deleted'状態である必要があります。"}

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

実際に関連付けられているエンティティへの参照を取得しようとしましたが、エンティティのはの代わりににEntityState設定されています。UnchangedDeleted

4

1 に答える 1

0

一般に、最初に親子関係の子をソフト削除する必要があります。最上位の親から始めて、子を再帰します。アクセスしたすべてのアイテムにマークを付けて、そのアイテムが既に論理削除されているかどうかを追跡できるようにします (後方参照の場合)。

「ビジネス オブジェクト」の概念がある場合は、ナビゲーションを容易にするためにプロパティをChilds追加できます。Parentそれ以外の場合は、重要な子関係を持つ各親でこれを「ハンドコーディング」する必要があります。

また、1 つの LINQ ステートメントを使用すると、実際のトラバースを制御できないことにも注意してください。

上記は大変な作業のように思えますが、必要な関係情報を自動的に推論するメカニズムを EF でどのように作成するかを考えてみてください! このようなことを適切に行うことになります。

于 2012-10-13T06:16:23.973 に答える