9

Entity Framework コードの使用 まず、次のようなものがあります。

public class Foo
{
    public int Id { get; set; }

    public List<Bar> Bars { get; set; }
}    

Foo foo = (from f in ctx.Foos.Include("Bars") where f.Id == 42 select f).Single();

// At this point foo.Bars is populated

ctx.Entry(foo).State = EntityState.Detached;

// At this point foo.Bars is an empty List

オブジェクトをデタッチするpublic List<string> Barsと、明示的に正常に含まれていたプロパティが空になるのはなぜですか?

多くのプロパティを持つ可能性のあるオブジェクトをデタッチする正しい手順は何ですか?

4

1 に答える 1

14

リストが空になる理由は、Entity Framework の 2 つのルールの組み合わせです。

  1. オブジェクトを切り離すと、このオブジェクト自体だけが切り離され、ナビゲーション プロパティが参照するオブジェクトは切り離されます。

  2. ObjectContext/は、DbContextコンテキストに部分的に接続され、部分的に切り離されたオブジェクト グラフを保持することを許可しません。これは、POCO を使用するときに一時的な状態として発生する可能性がありますが、EF は、さまざまなメソッド ( AddAttach、エンティティの状態の設定など) または latestSaveChangesが呼び出されたときに、切り離されたオブジェクトをグラフ内に自動的にアタッチすることにより、常にこの一時的な状態を修正します。

これは、コンテキストからルート オブジェクトをデタッチすると、EF が子のリストをクリアすることを意味します。これは、a) 子がアタッチされたままになる (ルール 1)、および b) グラフ内でデタッチされたオブジェクトとアタッチされたオブジェクトが混在することは許可されない (ルール2)。

私が知る限り、元のツリー構造を維持しながらコンテキストからオブジェクト グラフを切り離す方法はありません。親を切り離してから、子を次々に切り離すことができます。その結果、ツリーのすべてのオブジェクトをコンテキストから切り離しましたが、ツリーは同時に破棄され、各ナビゲーション プロパティが無効になります。

エンティティを手動でデタッチする主な目的は、メモリ リソースの制限があり、コンテキスト内に大量のオブジェクトを保持したくない、または保持する必要がない状況で、ガベージ コレクションのためにエンティティを解放することです。この目的のためには、グラフ構造が破棄されても問題ありません。

オブジェクトをコンテキストから切り離す必要がある理由がわかりません。ただし、 を使用するなど、そもそもエンティティをコンテキストにアタッチせずにデータベースからエンティティをロードするオプションもあることに注意してAsNoTracking()ください。

MSDN ドキュメントへの参照に関する問題に関する別の回答は、https ://stackoverflow.com/a/7693732/270591 です。

于 2012-04-27T00:22:59.873 に答える