web-dev-qa-db-ja.com

データコンテキストを破棄するタイミング

現在、アプリケーションのデータアクセスレイヤーを作成しています。アクセス層は、linqクラスを広範囲に使用してデータを返します。現在、データをデータベースに反映するために、プライベートデータコンテキストメンバーとパブリック保存メソッドを追加しました。コードは次のようになります。

private DataContext myDb;
public static MyClass GetMyClassById(int id)
{
    DataContext db = new DataContext();
    MyClass result = (from item in db.MyClasss
                      where item.id == id
                      select item).Single();
    result.myDb = db;
    return result;
}

public void Save()
{
    db.SubmitChanges();
}

それは単純化よりも大げさですが、それは一般的な考えを与えます。そのようなパターンを処理するより良い方法はありますか?データベースにアクセスするたびに新しいデータコンテキストをインスタンス化する必要がありますか?

54
Mykroft

それは実際にはあまり重要ではありません。 LINQ to SQLチームのMatt Warrenにこれについて少し前に聞いたところ、返答は次のとおりです。

IDisposableを実装した理由はいくつかあります。

アプリケーションロジックがDataContextが使用されるか、または有効であると予想されるときを超えてエンティティを保持する必要がある場合は、Disposeを呼び出すことによってそのコントラクトを強制できます。そのエンティティの遅延ローダーは引き続きDataContextを参照し、コードが遅延プロパティをナビゲートしようとすると、それを使用しようとします。これらの試みは失敗します。 Disposeはまた、DataContextにマテリアライズドエンティティのキ​​ャッシュを強制的にダンプさせるため、キャッシュされた単一のエンティティがそのDataContextを介してマテリアライズされたすべてのエンティティを誤って維持しないため、メモリリークのように見えます。

DataContext接続を自動的に閉じるロジックをだまして、接続を開いたままにすることができます。結果セットの最後に到達すると接続が閉じられるので、DataContextはクエリのすべての結果を列挙するアプリケーションコードに依存します。アプリケーションがC#またはVBのforeachステートメントの代わりにIEnumerableのMoveNextメソッドを使用する場合、列挙を途中で終了できます。アプリケーションで接続が閉じないという問題が発生し、自動終了動作が機能していないと思われる場合は、Disposeパターンを回避策として使用できます。

しかし、基本的には本当にはほとんどの場合それらを処分する必要はありません-これは仕様によるものです。私はとにかくそうする方が好きです。例外の負荷を覚えておくことよりも、「IDisposableを実装するすべてを破棄する」というルールに従う方が簡単だからです。ただし、リソースdo破棄するのを忘れます。

66
Jon Skeet

データコンテキストをリソースとして扱います。そして、リソースを使用するルールは言う

「できるだけ早くリソースを取得し、安全が確保されたらできるだけ早く解放してください」

16
Perpetualcoder

DataContextはかなり軽量であり、使用する作業単位アプリケーションを対象としています。ただし、DataContextをオブジェクトに保持することは考えていません。ビジネスオブジェクトを管理するためにデザイナーが生成したコードを使用しない場合は、リポジトリパターンを確認することをお勧めします。リポジトリパターンを使用すると、データコンテキストから切り離されたオブジェクトを操作し、更新などを行う前にそれらを再接続できます。

個人的には、DBMLデザイナが生成したコードの大部分を使用して、ビジネスと検証ロジックの部分的なクラス実装を行うことができます。また、デザイナーが生成したデータコンテキストを抽象化して継承し、データコンテキストに直接追加されるストアドプロシージャやテーブル値関数のメソッドなどをインターセプトして、そこにビジネスロジックを適用できるようにします。

ASP.NET MVCで使用しているパターンは、作業単位の必要に応じて適切なデータコンテキストを作成するファクトリクラスを挿入することです。ファクトリを使用すると、(1)既存のデータコンテキストクラスのラッパーを使用してモック可能(DataContextは簡単にモックできないため、ラッパーをモックする)と(2)Fake/Mockコンテキストを作成することで、データコンテキストをかなり簡単にモックアウトできます。そしてそれらを作成する工場。工場で自由自在に作れるので、長期間保管する必要がありません。

5
tvanfosson