LINQ to Entitiesでコンテキストをインスタンス化する
-
03-07-2019 - |
質問
コードでエンティティコンテキストを作成する際にプログラマがアプローチする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
}
}
どの方法がより効率的ですか?
DoSomething1()とDoSomething2()と呼ばれる2つのメソッドがあり、両方のメソッドにusingステートメントが組み込まれ、コンテキストを開いてそれで何でもできると仮定します。基本的に両方のメソッドがコンテキストを作成し、完了時にクリーンアップするため、メソッドを次々に呼び出す必要がありますか、余分なオーバーヘッドが発生しますか?クラスオブジェクトがインスタンス化されたときに作成され、オブジェクトがスコープ外になったときに順番にクリーンアップされるプライベート属性を1つだけ持つのとは対照的ですか?
解決
毎回新しいObjectContextを作成すると、「いくらか」のオーバーヘッドが発生します。基本的に、オーバーヘッドは、グローバルキャッシュから特定のObjectContextに関連付けられたメタデータにメタデータをコピーすることです。
このオーバーヘッドは比較的小さいので、特に使用パターンに固有の追加の安全性を考慮する場合、特に心配する価値はありません。
私にとってどのオプションを選択するかは、次のようなものに依存します:
- あなたの寿命はどれくらいですか ラップクラスになる可能性が高いですか?それが生きるなら 長い間ObjectContextは 多くのエンティティを保持するように成長する 時間の経過とともに減速します。だから新しい ObjectContextは毎回 良いアイデア。
- への呼び出しは ラッピングクラスのメソッド 同期? ObjectContext クラス自体はスレッドセーフではないため、 必要な2番目のパターンを使用します ラッピングクラスを確認する/ リポジトリはスレッドセーフです 複数のスレッドがそれを呼び出すことを期待します。
- メソッドは本質的に 無関係?その場合、メソッド間で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);
}