エンティティへのLINQでコンテキストをインスタンス化する

entity entity-framework linq linq-to-entities

質問

私は自分のコードでエンティティコンテキストを作成するときにプログラマがアプローチする2つの異なる方法を見ました。

最初のものはそのようなものです、そしてあなたはそれをすべてMSDNコード例の上に見つけることができます:

public void DoSomething() {
     using (TaxableEducationEntities context = new TaxableEducationEntities()) {
          // business logic and whatever else
     }
}

2つ目は、ビジネスロジックをカプセル化するクラスのプライベート属性としてコンテキストを作成することです。だからあなたは何かのようになるでしょう:

public class Education_LINQ {

        private TaxableEducationEntities context = new TaxableEducationEntities();

        public void DoSomething() {
            var result = from a in context.luAction
                         select a;

            // business logic and whatever else
        }
}

どちらがより効率的ですか?

1つはDoSomething1()、もう1つはDoSomething2()という2つのメソッドがあり、両方のメソッドにusingステートメントを組み込んでコンテキストを開き、それを使用して何でも実行するとします。基本的に両方のメソッドがコンテキストを作成し、完了したらそれをクリーンアップするため、余分なオーバーヘッドが発生しますか。クラスオブジェクトがインスタンス化されたときに作成され、オブジェクトがスコープ外になったときにクリーンアップされるプライベート属性を1つだけ持つのではなく、

受け入れられた回答

毎回新しいObjectContextを作成することは、いくらかのオーバーヘッドを伴います。本質的なオーバーヘッドは、グローバルキャッシュから特定のObjectContextに関連付けられたメタデータにメタデータをコピーすることです。

このオーバーヘッドは比較的小さいので、特に使用パターンに内在する特別な安全性を考えるときには、特に心配する価値はありません。

私にとってどちらのオプションを選択するかは、次のようなものによって異なります。

  1. あなたのラッピングクラスはどのくらい長持ちしますか?長期間存続する場合は、ObjectContextが大きくなり、時間の経過とともに減速する多数のエンティティを保持する可能性があります。そのため、毎回新しいObjectContextを使用することをお勧めします。
  2. ラッピングクラスのメソッド呼び出しは同期されていますか? ObjectContextクラス自体はスレッドセーフではないため、2番目のパターンを使用する場合は、複数のスレッドで呼び出すことを想定している場合は、ラッピングクラス/リポジトリがスレッドセーフであることを確認する必要があります。
  3. メソッドは本質的に無関係ですか?もしそうであれば、それらがメソッド間で1つのコンテキストを共有する場合、あなたは予期しない副作用を受けるかもしれません。

一般的に私のお勧めは、メソッドがステートレスであれば、つまり各メソッドの新しいコンテキストを起動して忘れることはおそらく良い考えです。

ただし、比較的短期間のステートフルフォームなどを使用している場合は、共有コンテキストを使用することをお勧めします。

更新:私はもっと完全な答えをまとめるのに時間をかけまし


人気のある回答

2番目のオプションは、それがあなたが意味するものであれば、実際にはそれ自身の後にクリーンアップしません。毎回ObjectContextバージョンを使用することを好みます。なぜなら、あとでそれを破棄する必要がないからです。私がその質問に正しく答えたのかどうかわからない…今日のプログラミングが多すぎる。

public class UserManagerRepository : IUserManagerRepository, IDisposable
{
    private readonly Entities _context = new Entities();
    private bool _disposed;

    public User Create(User user, int countryId)
    {
        user.Country = GetCountry(countryId);
        _context.AddToUser(user);
        _context.SaveChanges();
        return user;
    }
}

それからこのリポジトリを使うために、私は次のようにします。

using(var repository = new UserManagerRepository())
{
    repository.Create(user);
}


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ