遅延コレクションが不要になったときに、データベースコンテキストが適切に破棄されることをどのように保証しますか?


8

ここでベストプラクティスの種類の答えを探しています。

実装するクラスと対話するためのベストプラクティスIDisposableは次のUsingステートメントによるものであることを考えると、MVCでEFレイジーロードを使用するためのベストプラクティスは何ですか?

コントローラーメソッドの例:

<HttpGet>
Public Function Schedule(ByVal id As Int64) As ActionResult

    Dim model As Schedule = Nothing
    Using database As dataContext = New dataContext
        model = (From s In database.Schedules Where s.ScheduleID = id Select s).FirstOrDefault
    End Using

    Return View(theSchedule)

End Function

この例では、モデルがビューに到着するまでにデータベース[dataContext]が破棄されるため、遅延読み込みが機能しなくなります。

だから私は質問だと思います:
MVCで遅延読み込みを使用するためのベストプラクティスは何ですか?データベースコンテキストが適切に破棄され、メモリリークが発生しないことをどのように保証しますか?

回答:


9

一般に、UsingEntity Frameworkデータコンテキストでステートメントを使用する必要はありません。遅延コレクションは、その理由の1つです。したがって、コードは次のようになります。

<HttpGet>
Public Function Schedule(ByVal id As Int64) As ActionResult

    Dim model As Schedule = Nothing
    Dim database As dataContext = New dataContext
    model = (From s In database.Schedules Where s.ScheduleID = id Select s).FirstOrDefault

    Return View(model)

End Function

Entity Frameworkのデータコンテキストは、必要に応じて接続を開いたり閉じたりするように設計されており、データコンテキストオブジェクトが不要になると自動的に破棄されます。

DbContextのデフォルトの動作では、基になる接続は必要なときに自動的に開かれ、不要になったときに閉じられます。たとえば、クエリを実行し、「foreach」を使用してクエリ結果を反復処理する場合、IEnumerable.GetEnumerator()を呼び出すと接続が開かれ、後で使用可能な結果がなくなると、「foreach」が呼び出しを処理します接続を閉じる列挙子を破棄します。

注意が必要なのIDisposableOverride、データコンテキストのデフォルトの動作である場合のみです。

参考文献

常にDBContextでDisposeを呼び出す必要がありますか?いいえ。
Entity Framework 6で正しい方法でDbContextを管理する:詳細ガイド


4番目の文の後半が正しいかどうかはわかりません。「データコンテキストオブジェクトがスコープから外れると、自動的に破棄されます」。データコンテキストはビュー内の時間によってスコープから外れるため、例を使用すると、コンテキストは引き続き使用可能であり、それ自体が破棄されていませんか?何か不足していますか?
Sam Ax

いいえ。あなたの右; 言葉遣いが少しずさんだった。正しい説明は、DBContextが不要になったときにそれ自体を破棄するというものです。つまり、遅延コレクションは完全に列挙または破棄されます。私のアップデートをご覧ください。
Robert Harvey、

ロバート、これに答えてくれてありがとう。大変感謝しております。
Sam Ax

1
usingステートメントなしで正常に動作するDBContextがあると、必要に応じて、DBContextを依存関係注入するのがはるかに簡単になることに注意してください。
Robert Harvey、

DIは近い将来検討することになるので、覚えておきます。
サムアックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.